In this recent post we saw how to set our geographic location inside an AutoCAD drawing – essentially geo-referencing the model it contains – programmatically.
In today’s post we’re going to capture a section of the displayed map and embed it inside the drawing, much as the GEOMAPIMAGE command does. In fact, we’re going to use the GEOMAPIMAGE command to do most of the heavy lifting: we’ll simply call the command and then pick up the created GeomapImage object to manipulate its settings, adjusting some image properties (brightness, contrast and fade settings) and having the map image display hybrid (aerial + road) information.
Here’s the C# code implementing the CGI command, which should be run after the IGR command we implemented last time:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace GeoLocationAPI
{
public class Commands
{
[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."
);
}
}
}
}
Here’s a screencast of these two commands in action:
And here’s an image of the results, should you not want to spend 90s to get to the end of the above video. :-)