How to use a Callout in GeoGraphics?

It seems callout is only for plots and not for graphics :(

DynamicGeoGraphics[{Polygon[
Entity["City", {"Cambridge", "Massachusetts", "UnitedStates"}]],
Callout[GeoMarker[
Interpreter["StreetAddress"][
"14 James Way, Cambridge MA"]], "Hi"]}]


What is the preferred way to do styled callouts in geographics?

Also is there any way to get satellite image view instead of maps? Perhaps hooking up to the google maps api?

2 Answers

coords = First@Interpreter["StreetAddress"]["14 James Way, Cambridge MA"];


For the first part of the question, you can extract and post-process the callout graphics primitives from ListPlot[Callout[..]] and use them with GeoGraphics:

GeoGraphics[{Polygon[Entity["City", {"Cambridge", "Massachusetts", "UnitedStates"}]],
GeoMarker[coords, Style["\[FilledCircle]", 14, Blue]],
Cases[ListPlot[{Callout[coords, "Hi", "CalloutStyle" -> Red]}], _GraphicsGroup, All] /.
Offset[a_, b_] :> Offset[a, GeoPosition[b]]}]


Alternatively, you can use the CalloutMarker as the GeoMarker:

GeoGraphics[{Polygon[Entity["City", {"Cambridge", "Massachusetts", "UnitedStates"}]],
Cases[ListPlot[{Callout[coords, "Hi", "CalloutStyle" -> Red,
CalloutMarker -> "Star"]}], _GraphicsGroup, All] /.
{Offset[a_, b_] :> Offset[a, GeoPosition[b]],
Inset[a_, b_, c__] :> Inset[a, GeoGridPosition[GeoPosition[b], "Mercator"], c]}}]


With the options GeoProjection -> {"Bonne", "Centering" -> {0, 0}} and GeoRange -> "World" we get

• A very nice solution. I hope they will support Callouts and other graphics primitives in future versions, but in the meantime this is a really nice way to do it. – Carl Lange Mar 16 at 23:12
• Thank you @CarlLange. I agree it would be nice to have Callout working with additional functions. – kglr Mar 16 at 23:23
• @CarlLange This solution seems to have stopped working in v12 – M.R. Sep 8 at 4:50

Instead of importing the callout primitives from ListPlot into GeoGraphics, you can use Show to combine the GeoGraphics object with the ListPlot output as in this answer to Implementing GeoCallout?. Here's the GeoGraphics object:

bg = GeoGraphics[{Polygon[Entity["City",{"Cambridge","Massachusetts","UnitedStates"}]]}];


To use ListPlot, the geographic coordinates need to be converted to grid coordinates, which depend on the projection used:

coords = First @ Interpreter["StreetAddress"]["14 James Way, Cambridge MA"]
grid = First @ GeoGridPosition[GeoPosition[coords], Lookup[Options[bg], GeoProjection]]


{42.3702, -71.089}

{-71.089, 46.8615}

Now, use ListPlot to generate the callout:

listplot = ListPlot[{Callout[grid, "Here it is!", CalloutStyle->Red]}]


Finally, combine them, making sure to keep the GeoGraphics options:

Show[
bg,
listplot,
Options[bg]
]


• @CarlWikk This solution seems to have stopped working in v12 – M.R. Sep 8 at 4:51