Convert a long/lat on Mercator Projection with specific area and zoom to a (X,Y) point with VB.NET

168 views Asked by At

I'm trying to make an application that converts a Longitude and Latitude and will provide a relative point on a Mercator Projection map using VB.NET. However, differed from other examples, my code has to account for zooming into the SVG and also uses only a specific portion of a map.

I know that I can use this code to convert a global Mercator Projected map to a point (X,Y) with VB.NET but this example does not account for a specific area or zoom level.

This is a 'pseudocode' type example extracted from this answer on SO (View Here).

latitude    = 41.145556; // (φ)
longitude   = -73.995;   // (λ)

mapWidth    = 200;
mapHeight   = 100;

// get x value
x = (longitude+180)*(mapWidth/360)

// convert from degrees to radians
latRad = latitude*PI/180;

// get y value
mercN = ln(tan((PI/4)+(latRad/2)));
y     = (mapHeight/2)-(mapWidth*mercN/(2*PI));

I have taken a bit of time implementing this into VB.NET and it works fine when given a large mercator projection of the entire world.

However, the mercator map I am using only contains a small section of the world global mercator map and is a SVG file. (Download it here)

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.

My map application basically renders the SVG map as a bitmap (using the svg-net library) and loads it inside a PictureBox while accounting for zooming by a Scale Factor.

Eventually, I would want to obtain a function that when provided a long/lat will output a relative point of the PictureBox where the SVG is rendered. This is why zooming is important.

The function pseudocode above only accounts for getting a relative (x, y) on a worldwide mercator projection and doesn't account for scaling and a specific area at all.

This code is used to render the SVG map with zooming (if required):

Dim SF As String = 1 'Zoom/Scale Factor
'Use Scrollbar to Zoom PictureBox2 which contains the loaded bitmap
 Private Sub PictureBox2_MouseWheel(sender As Object, e As MouseEventArgs) Handles PictureBox2.MouseWheel
        If e.Delta > 0 Then
            SF = SF + 0.1
            Dim svgDocument = Svg.SvgDocument.Open("C:\users\admin\Pictures\doc.svg")
            svgDocument.ShapeRendering = SvgShapeRendering.Auto
            PictureBox2.Size = New Size(CInt(650 * SF), CInt(700 * SF))
            Dim bmp As Bitmap = svgDocument.Draw(PictureBox2.Size.Width, PictureBox2.Size.Height)
            PictureBox2.Image = bmp
        Else
            SF = SF - 0.1
            Dim svgDocument = Svg.SvgDocument.Open("C:\users\admin\Pictures\doc.svg")
            svgDocument.ShapeRendering = SvgShapeRendering.Auto
            PictureBox2.Size = New Size(CInt(650 * SF), CInt(700 * SF))
            Dim bmp As Bitmap = svgDocument.Draw(PictureBox2.Size.Width, PictureBox2.Size.Height)
            PictureBox2.Image = bmp
        End If
    End Sub

Is there any function that could be written when supplied the longitude and latitude of a area and a zoom factor would be able to return the relative (X,Y) coordinates of a SVG map?

I've been trying to figure out this for a long time but haven't found a good result.

0

There are 0 answers