Problem description
I am attempting to annotate some points in a scatter plot in a GeoMakie.jl geoaxis that contains a Tyler.jl maptile. None of my efforts so far turned out as expected. I suspect I need to find the appropriate transform to get my points (which I created simply using scatter for the longitude and latitude coordinates in the geoaxis) annotated but apparently it’s not simply a transformation to WebMercator (EPSG:3857).
TLDR;
Even though I can scatter using latitude and longitude coordinates, the annotations options (annotation! and text!) do not seem to take similar arguments as scatter does. I am unsure which are the right options to pick for conversion/coordinate transformation. I can get an approximately correct placement when I use annotation!() with the longitude and the Cartesian y coordinate multiplied by 10^(-6) but this seems quite convoluted and I would like to find a better way.
Example
Below is an example of the type of code I am attempting to run.
(I chose CairoMakie.jl because following the cartopy annotation example with GLMakie does not display any text at all, just the bounding box. I have not yet tried using WGLMakie)
using Tyler;
using Tyler.TileProviders;
using Tyler.Extents;
using GeoMakie;
using CairoMakie;
begin
# draw figure
f = Figure()
# Set up the plot extent and set the tile source
provider = TileProviders.Esri(:WorldImagery);
extent = Extent(X=(-10,-23), Y=(70.5,75.5));
# Create the axis in which to plot the tile
ga = GeoAxis(
f[1, 1];
dest="EPSG:3857",
source="EPSG:4326",
width=1200,
);
# Create the map and plot a point
m = Tyler.Map(extent; provider, figure=f, axis=ga); # Creates the maptiles with Tyler
scatter!(ga, -17.5, 72.2, markersize=15, color=:yellow); # displays a single dot at this (lon,lat)
# Using similar coordinates to scatter:
annotation!(ga, -18.2, 72.2, text="annotation", color=:white); # Ends up far north
text!(ga.scene, Point2f(-19.6, 72.2); text= "text", space = :relative, color=:white); # Not shown
# to get the points somewhere on screen:
annotation!(ga, -13, 3, text="annotation 2", color=:orange); # Point displayed at correct longitude but incorrect latitude
text!(ga.scene, Point2f(0.5, 0.6); text= "text 2", space = :relative, color=:orange); # Coordinates are between x = (0,1) and y = (0,1)
f
end
The above code results in the following figure:
The example from Tyler.jl documentation either does not display or shows an error depending on whether the geoaxis or the maptile is chosen as the target for the annotation:
using Tyler.MapTiles;
begin
# text example similar to that in Tyler.jl documentation
pts = Point2f(MapTiles.project((-19,73.2), MapTiles.wgs84, MapTiles.web_mercator));
text!(ga, pts, text = "Tyler point"; color = :magenta); # Doesn't show up in plot
text!(m, pts, text = "Tyler point"; color = :magenta); # Error: no method matching apply_transform(::Proj.Transformation, ::Tyler.Map{GeoAxis})
end
Map projection and other projections
So apparently the longitude is displayed correctly in annotation!() but the latitude i not:
annotation!(ga, -17.5, 15, text="lon -17.5,\n lat = 15", color=:magenta)
annotation!(ga, -17.5, 1, text="lon -17.5,\n lat = 1", color=:magenta)
Result:
Clearly the incorrect latitude is not the result of a WebMercator conversion:
using CoordRefSystems
using Unitful
begin
# Coordinate conversion:
newcoords = convert(CoordRefSystems.get(EPSG{3857}), LatLon(-17.5, 72.2))
lon = ustrip(newcoords.x) # result: 8.037267235274351e6
lat = ustrip(newcoords.y) # result: -1.9791064997243874e6
end
The best result is obtained by using the longitude and then using a Cartesian coordinate multiplied by 10^(-6).
julia> convert(Cartesian, LatLon(-17.5, 72.2))
Cartesian{WGS84Latest} coordinates
├─ x: 1.8600884659232805e6 m
├─ y: 5.793497226658212e6 m
└─ z: -1.905680220493041e6 m
begin
cartpts = convert(Cartesian, LatLon(-17.5, 72.2))
y = round(ustrip(cartpts.y) .* (10^-6) , digits=2)
annotation!(ga, -17.5, y, text="(-17.5, $y)", color=:lightgreen)
end
I would appreciate any insight. I am clearly missing something.
Thanks in advance!