I hadn’t planned on writing a third part to this series, but then Mads Paulin – who I mentioned in the last post – got back to me with some information that’s really worth sharing.
I’d pinged Mads while looking for a way to list the available coordinate systems to the user (another question from Coralie Jacobi, who had originally kicked off the series). I’d found out that the coordinate system definitions are primarily stored in this folder…
C:\ProgramData\Autodesk\Geospatial Coordinate Systems 14.01
… but I hadn’t worked out to extract any information from the contained CSD files.
Mads delivered the goods: he explained there’s a GeoCoordinateSystem class that contains a static method CreateAll(). The returned array of GeoCoordinateSystem classes can then be iterated, accessing the information you want from each one.
There’s also a static Create() method which lets you instantiate a single GeoCoordinateSystem class based on the XML you retrieve from the GeoLocation object. So we can now rip out our previous DynamicXML implementation (I’m glad we went through it, though: it’s still an interesting technique for people needing to retrieve data from XML). Mads will be happy: as the architect for the feature he was temporarily embarrassed by the hoops I ended up jumping through to get at this simple bit of information. :-)
Here’s the updated C# code. Look in particular for the new LCS (ListCoordinateSystems) command and the greatly simplified PrintCoordinateSystem() helper function. (The LLPF and PFLL commands should work just as they did, last time around, of course.)
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
namespace GeoLocationAPI
{
public class Commands
{
[CommandMethod("IGR")]
public void InsertGeoRef()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
return;
var ed = doc.Editor;
var db = doc.Database;
var msId = SymbolUtilityServices.GetBlockModelSpaceId(db);
if (HasGeoData(db))
{
// Report and return: could also open the object for
// write and modify its properties, of course
ed.WriteMessage("\nDrawing already has geo-location data!");
return;
}
// Let's create some geolocation data for this drawing,
// using a handy method to add it to the modelspace
// (it gets added to the extension dictionary)
var data = new GeoLocationData();
data.BlockTableRecordId = msId;
data.PostToDb();
// We're going to define our geolocation in terms of
// latitude/longitude using the Mercator projection
// http://en.wikipedia.org/wiki/Mercator_projection
data.CoordinateSystem = "WORLD-MERCATOR";
data.TypeOfCoordinates = TypeOfCoordinates.CoordinateTypeGrid;
// Use the lat-long for La Tene, my local "beach"
// (it's on a lake, after all :-)
var geoPt = new Point3d(7.019438, 47.005247, 0);
// Transform from a geographic to a modelspace point
// and add the information to our geolocation data
var wcsPt = data.TransformFromLonLatAlt(geoPt);
data.DesignPoint = wcsPt;
data.ReferencePoint = geoPt;
// Let's launch the GEOMAP command to show our geographic
// overlay
ed.Command("_.GEOMAP", "_AERIAL");
// Now we'll add a circle around our location
// and that will provide the extents for our zoom
using (var tr = db.TransactionManager.StartTransaction())
{
var ms =
tr.GetObject(msId, OpenMode.ForWrite) as BlockTableRecord;
if (ms != null)
{
// Add a red circle of 7K units radius
// centred on our point
var circle = new Circle(wcsPt, Vector3d.ZAxis, 7000);
circle.ColorIndex = 1;
ms.AppendEntity(circle);
tr.AddNewlyCreatedDBObject(circle, true);
}
tr.Commit();
}
// And we'll zoom to the circle's extents
ed.Command("_.ZOOM", "_OBJECT", "_L", "");
}
[CommandMethod("CGI")]
public void CreateGeoMapImage()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
return;
var ed = doc.Editor;
var db = doc.Database;
// Get the first corner of our area to convert to a
// GeomapImage
var ppo = new PromptPointOptions("\nSpecify first corner");
var ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
var first = ppr.Value;
// And get the second point as a corner (to rubber-band
// the selection)
var pco =
new PromptCornerOptions("\nSpecify second corner", first);
ppr = ed.GetCorner(pco);
if (ppr.Status != PromptStatus.OK)
return;
var second = ppr.Value;
// We'll use an event handler on the Database to check for
// GeomapImage entities being added
// (we'll use a lambda but assigned to a variable to be
// able to remove it, afterwards)
ObjectId giId = ObjectId.Null;
ObjectEventHandler handler =
(s, e) =>
{
if (e.DBObject is GeomapImage)
{
giId = e.DBObject.ObjectId;
}
};
// Simply call the GEOMAPIMAGE command with the two points
db.ObjectAppended += handler;
ed.Command("_.GEOMAPIMAGE", first, second);
db.ObjectAppended -= handler;
// Only continue if we've collected a valid ObjectId
if (giId == ObjectId.Null)
return;
// Open the entity and change some values
try
{
using (var tr = doc.TransactionManager.StartTransaction())
{
// Get each object and check if it's a GeomapImage
var gi =
tr.GetObject(giId, OpenMode.ForWrite) as GeomapImage;
if (gi != null)
{
// Let's adjust the brightmess/contrast/fade of the
// GeomapImage
gi.Brightness = 90;
gi.Contrast = 40;
gi.Fade = 20;
// And make sure it's at the right resolution and
// shows both aerial and road information
gi.Resolution = GeomapResolution.Optimal;
gi.MapType = GeomapType.Hybrid;
gi.UpdateMapImage(true);
}
tr.Commit();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception)
{
ed.WriteMessage(
"\nUnable to update geomap image entity." +
"\nPlease check your internet connectivity and call " +
"GEOMAPIMAGEUPDATE."
);
}
}
[CommandMethod("LCS")]
public void ListCoordinateSystems()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
return;
var ed = doc.Editor;
//
var css = GeoCoordinateSystem.CreateAll();
ed.WriteMessage("\nAvailable coordinate systems:\n");
int i=1;
foreach (var cs in css)
{
ed.WriteMessage("\n{0} {1}", i, cs.ID);
++i;
}
}
[CommandMethod("LLFP")]
public void LatLongFromPoint()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
return;
var ed = doc.Editor;
var db = doc.Database;
if (!HasGeoData(db))
{
ed.WriteMessage(
"\nCurrent drawing has no geo-location information."
);
return;
}
// Get the drawing point to be translated into a lat-lon
var ppo = new PromptPointOptions("\nSpecify point");
var ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
var dwgPt = ppr.Value;
// Translate the drawing point to a lat-lon
var res = TranslateGeoPoint(db, dwgPt, true);
// Print any coordinate system information
PrintCoordinateSystem(ed, res.Item2);
// And then the point itself
var lonlat = res.Item1;
ed.WriteMessage(
"\nLatitude-longitude is {0},{1}", lonlat.Y, lonlat.X
);
}
[CommandMethod("PFLL")]
public void PointFromLatLong()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
return;
var ed = doc.Editor;
var db = doc.Database;
if (!HasGeoData(db))
{
ed.WriteMessage(
"\nCurrent drawing has no geo-location information."
);
return;
}
// Get the latitude and longitude to be translated
// to a drawing point
var pdo = new PromptDoubleOptions("\nEnter latitude");
var pdr = ed.GetDouble(pdo);
if (pdr.Status != PromptStatus.OK)
return;
var lat = pdr.Value;
pdo.Message = "\nEnter longitude";
pdr = ed.GetDouble(pdo);
if (pdr.Status != PromptStatus.OK)
return;
var lon = pdr.Value;
var lonlat = new Point3d(lon, lat, 0.0);
// Translate the lat-lon to a drawing point
var res = TranslateGeoPoint(db, lonlat, false);
// Print any coordinate system information
ed.WriteMessage(res.Item2);
PrintCoordinateSystem(ed, res.Item2);
// And then the point itself
var dwgPt = res.Item1;
ed.WriteMessage(
"\nDrawing point is {0},{1},{2}", dwgPt.X, dwgPt.Y, dwgPt.Z
);
}
private static void PrintCoordinateSystem(Editor ed, string xml)
{
var gcs = GeoCoordinateSystem.Create(xml);
ed.WriteMessage("\nCoordinate system: {0}", gcs.ID);
}
private Tuple<Point3d, string> TranslateGeoPoint(
Database db, Point3d inPt, bool fromDwg
)
{
using (
var tr = db.TransactionManager.StartOpenCloseTransaction()
)
{
// Get the drawing's GeoLocation object
var gd =
tr.GetObject(db.GeoDataObject, OpenMode.ForRead)
as GeoLocationData;
// Get the output point...
// dwg2lonlat if fromDwg is true,
// lonlat2dwg otherwise
var outPt =
(fromDwg ?
gd.TransformToLonLatAlt(inPt) :
gd.TransformFromLonLatAlt(inPt)
);
var cs = gd.CoordinateSystem;
tr.Commit();
return new Tuple<Point3d, string>(outPt, cs);
}
}
private static bool HasGeoData(Database db)
{
// Check whether the drawing already has geolocation data
bool hasGeoData = false;
try
{
var gdId = db.GeoDataObject;
hasGeoData = true;
}
catch { }
return hasGeoData;
}
}
}
When we run the LCS command, we actually see the tail end of a looong list of coordinate systems:
6446 WGS72be/b.UTM-16N
6447 WGS72be/b.UTM-16S
6448 WGS72be/b.UTM-17N
6449 WGS72be/b.UTM-17S
6450 WGS72be/b.UTM-18N
6451 WGS72be/b.UTM-18S
6452 WGS72be/b.UTM-19N
6453 WGS72be/b.UTM-19S
6454 WGS72be/b.UTM-1N
6455 WGS72be/b.UTM-1S
6456 WGS72be/b.UTM-20N
6457 WGS72be/b.UTM-20S
6458 WGS72be/b.UTM-21N
6459 WGS72be/b.UTM-21S
6460 WGS72be/b.UTM-22N
6461 WGS72be/b.UTM-22S
6462 WGS72be/b.UTM-23N
6463 WGS72be/b.UTM-23S
6464 WGS72be/b.UTM-24N
6465 WGS72be/b.UTM-24S
6466 WGS72be/b.UTM-25N
6467 WGS72be/b.UTM-25S
6468 WGS72be/b.UTM-26N
6469 WGS72be/b.UTM-26S
6470 WGS72be/b.UTM-27N
6471 WGS72be/b.UTM-27S
6472 WGS72be/b.UTM-28N
6473 WGS72be/b.UTM-28S
6474 WGS72be/b.UTM-29N
6475 WGS72be/b.UTM-29S
6476 WGS72be/b.UTM-2N
6477 WGS72be/b.UTM-2S
6478 WGS72be/b.UTM-30N
6479 WGS72be/b.UTM-30S
6480 WGS72be/b.UTM-31N
6481 WGS72be/b.UTM-31S
6482 WGS72be/b.UTM-32N
6483 WGS72be/b.UTM-32S
6484 WGS72be/b.UTM-33N
6485 WGS72be/b.UTM-33S
6486 WGS72be/b.UTM-34N
6487 WGS72be/b.UTM-34S
6488 WGS72be/b.UTM-35N
6489 WGS72be/b.UTM-35S
6490 WGS72be/b.UTM-36N
6491 WGS72be/b.UTM-36S
6492 WGS72be/b.UTM-37N
6493 WGS72be/b.UTM-37S
6494 WGS72be/b.UTM-38N
6495 WGS72be/b.UTM-38S
6496 WGS72be/b.UTM-39N
6497 WGS72be/b.UTM-39S
6498 WGS72be/b.UTM-3N
6499 WGS72be/b.UTM-3S
6500 WGS72be/b.UTM-40N
6501 WGS72be/b.UTM-40S
6502 WGS72be/b.UTM-41N
6503 WGS72be/b.UTM-41S
6504 WGS72be/b.UTM-42N
6505 WGS72be/b.UTM-42S
6506 WGS72be/b.UTM-43N
6507 WGS72be/b.UTM-43S
6508 WGS72be/b.UTM-44N
6509 WGS72be/b.UTM-44S
6510 WGS72be/b.UTM-45N
6511 WGS72be/b.UTM-45S
6512 WGS72be/b.UTM-46N
6513 WGS72be/b.UTM-46S
6514 WGS72be/b.UTM-47N
6515 WGS72be/b.UTM-47S
6516 WGS72be/b.UTM-48N
6517 WGS72be/b.UTM-48S
6518 WGS72be/b.UTM-49N
6519 WGS72be/b.UTM-49S
6520 WGS72be/b.UTM-4N
6521 WGS72be/b.UTM-4S
6522 WGS72be/b.UTM-50N
6523 WGS72be/b.UTM-50S
6524 WGS72be/b.UTM-51N
6525 WGS72be/b.UTM-51S
6526 WGS72be/b.UTM-52N
6527 WGS72be/b.UTM-52S
6528 WGS72be/b.UTM-53N
6529 WGS72be/b.UTM-53S
6530 WGS72be/b.UTM-54N
6531 WGS72be/b.UTM-54S
6532 WGS72be/b.UTM-55N
6533 WGS72be/b.UTM-55S
6534 WGS72be/b.UTM-56N
6535 WGS72be/b.UTM-56S
6536 WGS72be/b.UTM-57N
6537 WGS72be/b.UTM-57S
6538 WGS72be/b.UTM-58N
6539 WGS72be/b.UTM-58S
6540 WGS72be/b.UTM-59N
6541 WGS72be/b.UTM-59S
6542 WGS72be/b.UTM-5N
6543 WGS72be/b.UTM-5S
6544 WGS72be/b.UTM-60N
6545 WGS72be/b.UTM-60S
6546 WGS72be/b.UTM-6N
6547 WGS72be/b.UTM-6S
6548 WGS72be/b.UTM-7N
6549 WGS72be/b.UTM-7S
6550 WGS72be/b.UTM-8N
6551 WGS72be/b.UTM-8S
6552 WGS72be/b.UTM-9N
6553 WGS72be/b.UTM-9S
6554 WGS84.AusAntarctic/LM
6555 WGS84.BLM-14NF
6556 WGS84.BLM-15NF
6557 WGS84.BLM-16NF
6558 WGS84.BLM-17NF
6559 WGS84.CanLam.3
6560 WGS84.CRTM05
6561 WGS84.PlateCarree
6562 WGS84.PseudoMercator
6563 WGS84.SCAR-SP19-20
6564 WGS84.SCAR-SP21-22
6565 WGS84.SCAR-SP23-24
6566 WGS84.SCAR-SQ01-02
6567 WGS84.SCAR-SQ19-20
6568 WGS84.SCAR-SQ21-22
6569 WGS84.SCAR-SQ37-38
6570 WGS84.SCAR-SQ39-40
6571 WGS84.SCAR-SQ41-42
6572 WGS84.SCAR-SQ43-44
6573 WGS84.SCAR-SQ45-46
6574 WGS84.SCAR-SQ47-48
6575 WGS84.SCAR-SQ49-50
6576 WGS84.SCAR-SQ51-52
6577 WGS84.SCAR-SQ53-54
6578 WGS84.SCAR-SQ55-56
6579 WGS84.SCAR-SQ57-58
6580 WGS84.SCAR-SR13-14
6581 WGS84.SCAR-SR15-16
6582 WGS84.SCAR-SR17-18
6583 WGS84.SCAR-SR19-20
6584 WGS84.SCAR-SR27-28
6585 WGS84.SCAR-SR29-30
6586 WGS84.SCAR-SR31-32
6587 WGS84.SCAR-SR33-34
6588 WGS84.SCAR-SR35-36
6589 WGS84.SCAR-SR37-38
6590 WGS84.SCAR-SR39-40
6591 WGS84.SCAR-SR41-42
6592 WGS84.SCAR-SR43-44
6593 WGS84.SCAR-SR45-46
6594 WGS84.SCAR-SR47-48
6595 WGS84.SCAR-SR49-50
6596 WGS84.SCAR-SR51-52
6597 WGS84.SCAR-SR53-54
6598 WGS84.SCAR-SR55-56
6599 WGS84.SCAR-SR57-58
6600 WGS84.SCAR-SR59-60
6601 WGS84.SCAR-SS04-06
6602 WGS84.SCAR-SS07-09
6603 WGS84.SCAR-SS10-12
6604 WGS84.SCAR-SS13-15
6605 WGS84.SCAR-SS16-18
6606 WGS84.SCAR-SS19-21
6607 WGS84.SCAR-SS25-27
6608 WGS84.SCAR-SS28-30
6609 WGS84.SCAR-SS31-33
6610 WGS84.SCAR-SS34-36
6611 WGS84.SCAR-SS37-39
6612 WGS84.SCAR-SS40-42
6613 WGS84.SCAR-SS43-45
6614 WGS84.SCAR-SS46-48
6615 WGS84.SCAR-SS49-51
6616 WGS84.SCAR-SS52-54
6617 WGS84.SCAR-SS55-57
6618 WGS84.SCAR-SS58-60
6619 WGS84.SCAR-ST01-04
6620 WGS84.SCAR-ST05-08
6621 WGS84.SCAR-ST09-12
6622 WGS84.SCAR-ST13-16
6623 WGS84.SCAR-ST17-20
6624 WGS84.SCAR-ST21-24
6625 WGS84.SCAR-ST25-28
6626 WGS84.SCAR-ST29-32
6627 WGS84.SCAR-ST33-36
6628 WGS84.SCAR-ST37-40
6629 WGS84.SCAR-ST41-44
6630 WGS84.SCAR-ST45-48
6631 WGS84.SCAR-ST49-52
6632 WGS84.SCAR-ST53-56
6633 WGS84.SCAR-ST57-60
6634 WGS84.TM-116SE
6635 WGS84.TM-132SE
6636 WGS84.TM-36SE
6637 WGS84.TM-6NE
6638 WGS84.UPSNorth
6639 WGS84.UPSSouth
6640 WGS84.USGS-AntarticMtn
6641 WGS84.Winkel
6642 WI-C
6643 WI-N
6644 WI-S
6645 WI27-TM
6646 WI83-C
6647 WI83-CF
6648 WI83-N
6649 WI83-NF
6650 WI83-S
6651 WI83-SF
6652 WI83-TM
6653 WIHP-C
6654 WIHP-CF
6655 WIHP-N
6656 WIHP-NF
6657 WIHP-S
6658 WIHP-SF
6659 WilkinMN-F
6660 WilkinMN-IF
6661 WilkinMN-M
6662 WinnebagoWI-F
6663 WinnebagoWI-IF
6664 WinnebagoWI-M
6665 WinonaMN-F
6666 WinonaMN-IF
6667 WinonaMN-M
6668 WisconsinTM-HP
6669 WoodWI-F
6670 WoodWI-IF
6671 WoodWI-M
6672 WORLD-EQDIST-CYL
6673 WORLD-LL
6674 WORLD-LM-CONIC
6675 WORLD-LM-TAN
6676 WORLD-MERCATOR
6677 WORLD-MILLER
6678 WORLD-ROBINSON
6679 WORLD-SINUSOIDAL
6680 WORLD-VDGRNTN
6681 WrightMN-F
6682 WrightMN-IF
6683 WrightMN-M
6684 WSIG
6685 WV-N
6686 WV-S
6687 WV83-N
6688 WV83-NF
6689 WV83-S
6690 WV83-SF
6691 WVHP-N
6692 WVHP-NF
6693 WVHP-S
6694 WVHP-SF
6695 WY-E
6696 WY-EC
6697 WY-W
6698 WY-WC
6699 WY83-E
6700 WY83-EC
6701 WY83-ECF
6702 WY83-EF
6703 WY83-W
6704 WY83-WC
6705 WY83-WCF
6706 WY83-WF
6707 WYHP-E
6708 WYHP-EC
6709 WYHP-ECF
6710 WYHP-EF
6711 WYHP-W
6712 WYHP-WC
6713 WYHP-WCF
6714 WYHP-WF
6715 Xian80.GK-13
6716 Xian80.GK-14
6717 Xian80.GK-15
6718 Xian80.GK-16
6719 Xian80.GK-17
6720 Xian80.GK-18
6721 Xian80.GK-19
6722 Xian80.GK-20
6723 Xian80.GK-21
6724 Xian80.GK-22
6725 Xian80.GK-23
6726 Xian80.GK/CM-105E
6727 Xian80.GK/CM-111E
6728 Xian80.GK/CM-117E
6729 Xian80.GK/CM-123E
6730 Xian80.GK/CM-129E
6731 Xian80.GK/CM-135E
6732 Xian80.GK/CM-75E
6733 Xian80.GK/CM-81E
6734 Xian80.GK/CM-87E
6735 Xian80.GK/CM-93E
6736 Xian80.GK/CM-99E
6737 Xian80.GK3d-25
6738 Xian80.GK3d-26
6739 Xian80.GK3d-27
6740 Xian80.GK3d-28
6741 Xian80.GK3d-29
6742 Xian80.GK3d-30
6743 Xian80.GK3d-31
6744 Xian80.GK3d-32
6745 Xian80.GK3d-33
6746 Xian80.GK3d-34
6747 Xian80.GK3d-35
6748 Xian80.GK3d-36
6749 Xian80.GK3d-37
6750 Xian80.GK3d-38
6751 Xian80.GK3d-39
6752 Xian80.GK3d-40
6753 Xian80.GK3d-41
6754 Xian80.GK3d-42
6755 Xian80.GK3d-43
6756 Xian80.GK3d-44
6757 Xian80.GK3d-45
6758 Xian80.GK3d/CM-102E
6759 Xian80.GK3d/CM-105E
6760 Xian80.GK3d/CM-108E
6761 Xian80.GK3d/CM-111E
6762 Xian80.GK3d/CM-114E
6763 Xian80.GK3d/CM-117E
6764 Xian80.GK3d/CM-120E
6765 Xian80.GK3d/CM-123E
6766 Xian80.GK3d/CM-126E
6767 Xian80.GK3d/CM-129E
6768 Xian80.GK3d/CM-132E
6769 Xian80.GK3d/CM-135E
6770 Xian80.GK3d/CM-75E
6771 Xian80.GK3d/CM-78E
6772 Xian80.GK3d/CM-81E
6773 Xian80.GK3d/CM-84E
6774 Xian80.GK3d/CM-87E
6775 Xian80.GK3d/CM-90E
6776 Xian80.GK3d/CM-93E
6777 Xian80.GK3d/CM-96E
6778 Xian80.GK3d/CM-99E
6779 Xian80.LL
6780 XY-BC
6781 XY-BL
6782 XY-BR
6783 XY-CA
6784 XY-CC
6785 XY-CF
6786 XY-CG
6787 XY-CL
6788 XY-CM
6789 XY-DAM
6790 XY-DK
6791 XY-DM
6792 XY-FT
6793 XY-FU
6794 XY-GC
6795 XY-GL
6796 XY-GM
6797 XY-HM
6798 XY-IFT
6799 XY-IIN
6800 XY-IMI
6801 XY-IN
6802 XY-IYD
6803 XY-KM
6804 XY-KT
6805 XY-M
6806 XY-MI
6807 XY-ML
6808 XY-MM
6809 XY-NM
6810 XY-PE
6811 XY-PO
6812 XY-RD
6813 XY-RO
6814 XY-SC
6815 XY-SL
6816 XY-SY
6817 XY-UI
6818 XY-YD
6819 Yacare.LL
6820 Yacare/E.LL
6821 YAP
6822 YellowMedicineMN-F
6823 YellowMedicineMN-IF
6824 YellowMedicineMN-M
6825 YEM-E
6826 YEM-GK7
6827 YEM-GK8
6828 YEM-GK9
6829 YEM-U37
6830 YEM-U38
6831 YEM-U39
6832 YEM-W
6833 Yemen96.UTM-38N
6834 Yemen96.UTM-39N
6835 YemenNtl96.LL
6836 ZAIRE
6837 Zanderij.LL
6838 Zanderij.SurinameTM
6839 Zanderij.SurinameTMOld
6840 Zanderij.TM-54NW
6841 Zanderij.UTM-21N
6842 ZIM-35
6843 ZIM-35/01
6844 ZIM-36
6845 ZIM-36/01
So we can see we have 6845 available to us (many more than the list shown inside AutoCAD 2015). I’m not sure how best they’d be filtered or categorised – this isn’t my specialist field, of course – but if someone has a request/suggestion for how to do so, please do post a comment. A lot more can clearly be done with this list than just printing the ID of each entry.
Update:
Mads tells me the library we use contains more coordinate systems than AutoCAD supports: AutoCAD only currently works with “projected” coordinate systems (the others in the list are used by other Autodesk products). You can modify the LCS command to filter the list by wrapping the contents of its foreach loop in an if statement, e.g.:
if (cs.Type == GeoCSType.Projected)
{
ed.WriteMessage("\n{0} {1}", i, cs.ID);
++i;
}
That reduces the list down to 6132 coordinate systems that can be used by AutoCAD. Which should still be plenty, I would think. Thanks, Mads!