I have a map of the world as SVG file using the Robinson projection on which I would like to place a circle. The width of the map/image is X (2754) and its heigth is Y (1398). I would like to place the center of the circle at Lat 40.7127, Long -74.0059 (New York City). How can I calculate, based on the coordinates at which position X,Y on the map, I have to place the circle to correctly point out New York City? I would also be happy to use another SVG of the world as long as it uses the Robinson projection and allows me some styling options such as lines between countries, possibly color of the ocean etc.
-
2The details for how Robinson projections are made is on the Wikipedia article you link, but given "Robinson did not specify any particular interpolation method" and a lack of metadata in that SVG (eg the geoid and datum used) you might struggle with precision,.– SpacedmanCommented Jun 13, 2019 at 10:03
-
@Spacedman's concern about precision is valid, but assuming you're making a several pixel circle on a 1400x2800 pixel map, probably not fatal, i.e. any reasonable interpolation algorithm, geoid, and datum assumption will get you within reasonable visual precision on your map (i.e. 10 hours rush hour traffic travel time :) )– HouskaCommented Jun 21, 2019 at 11:57
1 Answer
The proj
utility (standalone proj.org, or e.g. bundled with QGIS) can help.
$ proj +proj=robin
-74.0059 40.7127
-6420016.35 4352037.34
-180 0
-17005833.33 -0.00
0 90
0.00 8625155.13
180 0
17005833.33 -0.00
^C
The above gives your NYC point converted to X,Y in metres in Robinson projection (the -6420016 4352037), together with lat long +-180 and +-90 which are probably the left edge, top, and right edge of your map image. You can then convert to your image pixel coordinates linearly, e.g. -6420016 maps to 2754 * (-6420016 - (-17005833)) / (2* 17005833) = 857 in the x dimension, similarly for y (I get 1052).
You'll likely have to adjust this for which corner you're counting pixels from, and the specifics of your map image, in particular what is the central meridian, and whether it has the full world extent (compare it visually with this default). If they don't fully match, the +lon_0
parameter to proj
can help, and potentially false easting and false northing and/or +k_0
.
-
First of all, thank you for your answer!! It already contains very useful hints but may not answer my question yet ... let's see :) The
x-value
should simply be the value you've given me. The y value I suppose is the mapHeigth (1398) minus 1052. Unfortunately, this places my circle somewhere in Newfoundland. Does that still count as "inaccuracies" that I have to iron out or is there something wrong with the approach. You can try this yourself by adding<circle fill="red" cx="857" cy="346" r="10"/>
before the</svg>
in the end of the file. I will look into Proj now :) Thanks!!– StückeCommented Jun 21, 2019 at 13:15 -
the answer is great, but as far as I can see the assumption that the map goes from -90 to 90 is probably wrong: If I see well a part of the North pole is too much. One should thus find the value of this shift (e.g. based on the true position of an island), then it can be applied to all new coordinates– radouxjuCommented Jun 21, 2019 at 13:25
-
Maybe I can just draw an SVG image of the world with Robinson projection with Proj which I then use ... I guess then it is easier to make sure that the coordiantes/assumptions match.– StückeCommented Jun 21, 2019 at 13:26
-
1@Jonas, I think the approach is sound but it's tricky since you don't know the precise extent of the rendering in the SVG. I think if you can, drawing a Robinson projection map where you control the parameters may well be easier. Otherwise, you could try plotting some known, extreme points (like Svalbard, etc, as well as poles) or overlaying the "canonical" Robinson map at proj.org/_images/robin.png on top of your svg to determine appropriate fudge factors. All those fudge factors should affect only the linear transformation from (x,y) in meters outputted by proj into image pixels.– HouskaCommented Jun 21, 2019 at 13:35
-
1@Jonas, re the matplotlib approach (comment above). I took the image there at matplotlib.org/basemap/_images/robin.png, cropped it and scaled it up crudely (image editing software) to height 1398 pixels and checked that pixel (857,346) is indeed NYC. So the problem is indeed that your SVG has mystery nonstandard parameters, not the proj algorithm.– HouskaCommented Jun 21, 2019 at 13:44