question

blinkor12-6317 avatar image
0 Votes"
blinkor12-6317 asked blinkor12-6317 commented

VB.NET Get Relative Point/Coordinates in Mercator Zoomed Map

I'm attempting to make a map renderer inside a PictureBox with VB.NET. I'm trying to convert a map (with Mercator) projection when given a Longitude and Latitude value and a zoomed factor would convert it to a pixel point location.

I've found several examples of converting a Mercator projection-based map's longitude and latitude but they either are using a world map (I'm using a specific area of that map) or don't account or use a different type of Scale Factor.

My map rendering application takes a SVG and loads it with the SVG-NET library as a bitmap into a PictureBox with a variable that contains a Zoom Factor.

I'm trying to write a function that when given the zoom factor, longitude, and latitude will output the relative location of that point inside a PictureBox.

This is the code I use to render the SVG into the PictureBox.

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


I know that the SVG's default width is 450 and the height is 530. I also know that the left longitude is "123.658963" and the top latitude is "45.523885" and the right longitude is "145.820743" and the bottom latitude is "24.217586".

How can I write a function for this?

The SVG can be downloaded from here: Google Drive Link


dotnet-visual-basic
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

XingyuZhao-MSFT avatar image
0 Votes"
XingyuZhao-MSFT answered blinkor12-6317 commented

Hi @blinkor12-6317 ,
Do you consider scaling the picture in the following ways.
93256-gif.gif
If so, you need to create a custom PictureBox(code from here).

 Public Class CustomPictureBox
     Inherits System.Windows.Forms.UserControl
    
     Private PicBox As System.Windows.Forms.PictureBox
     Private OuterPanel As Panel
     Private components As Container = Nothing
     Private m_sPicName As String = ""
     Private ZOOMFACTOR As Double = 1.25
     Private MINMAX As Integer = 5
    
     Private Sub InitializeComponent()
         Me.PicBox = New System.Windows.Forms.PictureBox()
         Me.OuterPanel = New System.Windows.Forms.Panel()
         Me.OuterPanel.SuspendLayout()
         Me.SuspendLayout()
         Me.PicBox.Location = New System.Drawing.Point(0, 0)
         Me.PicBox.Name = "PicBox"
         Me.PicBox.Size = New System.Drawing.Size(150, 140)
         Me.PicBox.TabIndex = 3
         Me.PicBox.TabStop = False
         Me.OuterPanel.AutoScroll = True
         Me.OuterPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
         Me.OuterPanel.Controls.Add(Me.PicBox)
         Me.OuterPanel.Dock = System.Windows.Forms.DockStyle.Fill
         Me.OuterPanel.Location = New System.Drawing.Point(0, 0)
         Me.OuterPanel.Name = "OuterPanel"
         Me.OuterPanel.Size = New System.Drawing.Size(210, 190)
         Me.OuterPanel.TabIndex = 4
         Me.Controls.Add(Me.OuterPanel)
         Me.Name = "CustomPictureBox"
         Me.Size = New System.Drawing.Size(210, 190)
         Me.OuterPanel.ResumeLayout(False)
         Me.ResumeLayout(False)
     End Sub
    
     Public Sub New()
         InitializeComponent()
         InitCtrl()
     End Sub
    
     Private _pictureImage As Image
    
     Public Property PictureImage As Image
         Get
             Return _pictureImage
         End Get
         Set(ByVal value As Image)
    
             If value IsNot Nothing Then
    
                 Try
                     PicBox.Image = value
                     _pictureImage = value
                 Catch ex As OutOfMemoryException
                     RedCross()
                 End Try
             Else
                 RedCross()
             End If
         End Set
     End Property
    
     <Browsable(False)>
     Public Property Picture As String
         Get
             Return m_sPicName
         End Get
         Set(ByVal value As String)
    
             If value IsNot Nothing Then
    
                 If System.IO.File.Exists(value) Then
    
                     Try
                         PicBox.Image = Image.FromFile(value)
                         m_sPicName = value
                     Catch ex As OutOfMemoryException
                         RedCross()
                     End Try
                 Else
                     RedCross()
                 End If
             End If
         End Set
     End Property
    
     <Browsable(False)>
     Public Property Border As BorderStyle
         Get
             Return OuterPanel.BorderStyle
         End Get
         Set(ByVal value As BorderStyle)
             OuterPanel.BorderStyle = value
         End Set
     End Property
    
     Private Sub InitCtrl()
         PicBox.SizeMode = PictureBoxSizeMode.StretchImage
         PicBox.Location = New Point(0, 0)
         OuterPanel.Dock = DockStyle.Fill
         OuterPanel.Cursor = System.Windows.Forms.Cursors.NoMove2D
         OuterPanel.AutoScroll = True
         AddHandler OuterPanel.MouseEnter, AddressOf PicBox_MouseEnter
         AddHandler PicBox.MouseEnter, AddressOf PicBox_MouseEnter
         AddHandler OuterPanel.MouseWheel, AddressOf PicBox_MouseWheel
     End Sub
    
     Private Sub RedCross()
         Dim bmp As Bitmap = New Bitmap(OuterPanel.Width, OuterPanel.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555)
         Dim gr As Graphics
         gr = Graphics.FromImage(bmp)
         Dim pencil As Pen = New Pen(Color.Red, 5)
         PicBox.Image = bmp
         gr.Dispose()
     End Sub
    
     Private Sub ZoomIn()
         If (PicBox.Width < (MINMAX * OuterPanel.Width)) AndAlso (PicBox.Height < (MINMAX * OuterPanel.Height)) Then
             PicBox.Width = Convert.ToInt32(PicBox.Width * ZOOMFACTOR)
             PicBox.Height = Convert.ToInt32(PicBox.Height * ZOOMFACTOR)
             PicBox.SizeMode = PictureBoxSizeMode.StretchImage
         End If
     End Sub
    
     Private Sub ZoomOut()
         If (PicBox.Width > (OuterPanel.Width / MINMAX)) AndAlso (PicBox.Height > (OuterPanel.Height / MINMAX)) Then
             PicBox.SizeMode = PictureBoxSizeMode.StretchImage
             PicBox.Width = Convert.ToInt32(PicBox.Width / ZOOMFACTOR)
             PicBox.Height = Convert.ToInt32(PicBox.Height / ZOOMFACTOR)
         End If
     End Sub
    
     Private Sub PicBox_MouseWheel(ByVal sender As Object, ByVal e As MouseEventArgs)
         If e.Delta < 0 Then
             ZoomIn()
         Else
             ZoomOut()
         End If
     End Sub
    
     Private Sub PicBox_MouseEnter(ByVal sender As Object, ByVal e As EventArgs)
         If PicBox.Focused = False Then
             PicBox.Focus()
         End If
     End Sub
    
     Protected Overrides Sub Dispose(ByVal disposing As Boolean)
         If disposing Then
             If components IsNot Nothing Then components.Dispose()
         End If
    
         MyBase.Dispose(disposing)
     End Sub
 End Class

Then use this:

         Dim svgDocument = Svg.SvgDocument.Open("...svg")
         svgDocument.ShapeRendering = SvgShapeRendering.Auto
         Dim bmp As Bitmap = svgDocument.Draw(PictureBox1.Width, PictureBox1.Height)
         CustomPictureBox1.PictureImage = bmp

Best Regards,
Xingyu Zhao


If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



gif.gif (220.8 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

So I can use this zoom factor to multiply with the relative zoom for figuring out the Mercator projection?

0 Votes 0 ·