I recently wrote a function that gets a relative point on a Mercator Projection map from a coordinate.
The map I'm using is a svg
while it is not zoomed. Download SVG @ Google Drive Link
This code and function is expected to get the relative point of the SVG
when it is rendered as a bitmap inside a PictureBox
. The problem is that the point outputted by the function does not match up with what I expected.
In the below image of the SVG
rendered as a bitmap with no zoom, I have marked a green point, where I expect it to get the point of and a red point, where the function actually gives me.
I have written this code to get the relative point of the SVG
from the longitude and latitude of the SVG.
Private Sub fs_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox(ConvertGeoToPixel(35.652832, 139.839478, 450, 530, 123.658963, 145.820743, 24.217586).ToString())
End Sub
Private Function ConvertGeoToPixel(ByVal latitude As Double, ByVal longitude As Double, ByVal imageWidth As Integer, ByVal imageHeight As Integer, ByVal mapLonLeft As Double, ByVal mapLonRight As Double, ByVal mapLatBottom As Double) As Point
Dim mapLatBottomRad As Double = mapLatBottom * Math.PI / 180
Dim latitudeRad As Double = latitude * Math.PI / 180
Dim mapLonDelta As Double = mapLonRight - mapLonLeft
Dim worldMapWidth As Double = (imageWidth / mapLonDelta * 360) / (2 * Math.PI)
Dim mapOffsetY As Double = worldMapWidth / 2 * Math.Log((1 + Math.Sin(mapLatBottomRad)) / (1 - Math.Sin(mapLatBottomRad)))
Dim x As Double = (longitude - mapLonLeft) * (imageWidth / mapLonDelta)
Dim y As Double = imageHeight - ((worldMapWidth / 2 * Math.Log((1 + Math.Sin(latitudeRad)) / (1 - Math.Sin(latitudeRad)))) - mapOffsetY)
Return New Point() With {
.X = Convert.ToInt32(x),
.Y = Convert.ToInt32(y)
}
End Function
I know the map's width
is 450 and the height
is 530. I also know that when not zoomed at all, the map's left longitude is 123.658963
and its top latitude is 45.523885
and its right longitude is 145.820743
and its bottom latitude is 24.217586
. This information was included in the source where I downloaded the SVG map. I incorporated this information into the SVG.
The output of this is very off (shown on the image) is:
{X=329,Y=261}
which is very off.
I'm not sure whats going on. What can I do to fix this?
The conversion is a straight linear conversion. The longitude adjustment for latitude has already been done for you in the SVG. Just calculate the scale and offset for the latitude and longitude.