Best Way to Programmatically Identify a Coordinate System?

Best Way to Programmatically Identify a Coordinate System?

CodeDing
Advisor Advisor
598 Views
5 Replies
Message 1 of 6

Best Way to Programmatically Identify a Coordinate System?

CodeDing
Advisor
Advisor

Hey all,

 

Looking for some guidance here. The overarching question is:

What is the best way to programmatically identify a coordinate system?

I understand that there are Projected, Geodetic, Arbitrary, etc ...Coordinate Systems. So perhaps for sake of taking a first step, the question could be:

What is the best way to programmatically identify a projected coordinate system?

 

It should also be assumed that enough information necessary to identify the coordinate system is present (e.g. Ellipsoid name/flattening/radius/etc, Projection scale/false northing/false easting/etc, Datum name/realization/etc). Also, the data can be in any format necessary (JSON, XML, WKT, etc).

 

So even if I have all of this data, HOW can I programmatically (using any programming language, ideally .NET or Python) output, with ##% confidence, something like:
- EPSG 2232

- Custom CS, based on EPSG 2232

- Arbitrary CS

 

I would like to ultimately retrieve this information from a source, open Civil 3D, and automatically assign a coordinate system (assuming I have sufficient information/confidence to do so).

 

As always, any input is appreciated.

Best,

~DD

0 Likes
599 Views
5 Replies
Replies (5)
Message 2 of 6

rampseeker
Advocate
Advocate

I retrieve the coordinate system code using this method

[CommandMethod ("printCoordinate")]
public static void PrintCoordinateSystemCode()
{
    var doc = Application.DocumentManager.MdiActiveDocument;
    var ed = doc.Editor;
    var civDoc = CivilApplication.ActiveDocument;

    // getCoordinateSystemCode
    string csCode = civDoc.Settings
                            .DrawingSettings
                            .UnitZoneSettings
                            .CoordinateSystemCode;

    if (string.IsNullOrEmpty(csCode))
    {
        ed.WriteMessage("\nNo coordinate system is set for this drawing.");
    }
    else
    {
        ed.WriteMessage($"\nCurrent coordinate system code: {csCode}");
    }
}
0 Likes
Message 3 of 6

CodeDing
Advisor
Advisor

@rampseeker ,

 

Thanks for the reply! I can easily get the CS Code with the System Variable CGEOCS. My main goal is rather identifying a system by all of it's definition properties. In essence, if I had everything BUT the CGEOCS code, how would I determine a CGEOCS code lol

 

Best, 

~DD

0 Likes
Message 4 of 6

Anton_Huizinga
Advocate
Advocate

You can request the current Coordinate System with this code:

 

        public static acDbServ.GeoCoordinateSystem GetCurrentCoordinateSystem()
        {

            acDbServ.GeoCoordinateSystem returnValue = null;
            string name = string.Empty;

            acDbServ.Database db = acAppServ.Application.DocumentManager.MdiActiveDocument.Database;
            using (acDbServ.Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    if (db.GeoDataObject != acDbServ.ObjectId.Null)
                    {
                        acDbServ.GeoLocationData gd = tr.GetObject(db.GeoDataObject, acDbServ.OpenMode.ForRead) as acDbServ.GeoLocationData;

                        Match matchName = Regex.Match(gd.CoordinateSystem, "<Name>(.*?)</Name>");
                        if (matchName.Success)
                        {
                            name = matchName.Groups[1].Value;
                        }

                        if (name != string.Empty)
                        {
                            foreach (acDbServ.GeoCoordinateSystem cs in acDbServ.GeoCoordinateSystem.CreateAll())
                            {
                                if (cs.ID == name)
                                {
                                    returnValue = cs;
                                    break;
                                }
                            }
                        }
                    }
                }
                catch (System.Exception ex) { }

                tr.Commit();
            }

            return returnValue;
        }

The returned object can be read further, if I remember correctly, you can see if it is projected and read the WKT stuff and so on.

 

If you want all 6000+ available Coordinate Systems, you can use this code:

       public static List<acDbServ.GeoCoordinateSystem> GetAllValidCoordinateSystems()
        {

            List<acDbServ.GeoCoordinateSystem> returnValue = new List<acDbServ.GeoCoordinateSystem>();

            List<string> ignoreItems = new List<string>() { "obsolete", "deprecated", "replaced by", "for testing only", "incorrect", "legacy use" };

            foreach (acDbServ.GeoCoordinateSystem cs in acDbServ.GeoCoordinateSystem.CreateAll())
            {
                if (cs.Type == acDbServ.GeoCSType.Projected)
                {
                    string description = cs.Description.Trim().ToLower();
                    if (ignoreItems.Any(s => description.Contains(s)) == false) { returnValue.Add(cs); }
                }
            }

            return returnValue;
        }

 

Message 5 of 6

CodeDing
Advisor
Advisor

@Anton_Huizinga ,

 

That's useful information! I'm semi familiar with retrieving the CS Dictionary XML data. Perhaps this would be one step of the entire process. But my question would still remain: 

 

If I had everything BUT the CGEOCS code, how would I determine a CGEOCS code?

 

It's a very nuanced question and definitely not easy to answer.

 

Best, 

~DD

0 Likes
Message 6 of 6

Anton_Huizinga
Advocate
Advocate

I guess you could walk through all available CS and then compare as many as values. 

0 Likes