首页 > 解决方案 > 具有特定区域和缩放功能的可缩放墨卡托 SVG 像素转换器 (VB.NET)

问题描述

我正在尝试使用特定文件制作自己的地图渲染引擎,SVG以便可以在没有任何第三方资源(例如在线谷歌地图)的情况下使用 VB.NET 加载它。

此地图可以拖动(移动 - 这不会在转换中考虑)、缩放(SVG 的原因),以及从静态文件或XDocument变量从 SVG 加载。

我的目标是我正在尝试创建一个函数,在该函数中我可以GDISystem.Drawing渲染地图的特定点绘制对象。我计划在 a 中渲染地图,每次缩放都会刷新并在特定级别PictureBox重新渲染地图。SVG我的最终目标是有一种方法可以渲染这种类型的地图,并且能够在GDI地图上的特定经度/纬度点绘制对象。

例如,如果我想在 的经度点和 的纬度点绘制circle半径为 100 英里的,我会将经度和纬度传递给一个函数,以通过考虑缩放级别和其他来获取 中的相对点有关(例如 SVG 地图的边界)的信息,并返回在地图上呈现特定位置的相对点对。我创建了一个图解示例以在下面可视化这一点。 重要的是要考虑缩放 SVG 的方法是特殊的,以使事情变得更容易。例如,当用户请求将 放大到 2 的缩放因子时,地图的大小将被调整为当前大小的 2 倍(如果的大小是35.011665135.768326PictureBoxSVGPictureBox图片框流SVGPictureBox10,10(20,20)) 并且 SVG 被重绘以适合picturebox自身。为了像实际地图一样拖动它,将注册点击事件,用户将PictureBox自己移动实际地图。这可能会占用大量内存,但这个问题超出了这个问题的范围。

我已经尝试解决这个问题。这是我的代码,它不考虑比例因子,但只考虑包含特定区域的地图。另外,它根本不起作用,并且将点定位得太远。

    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

这个功能不起作用。

此代码用于渲染 SVG。它使用库 SVG-NET.:

'LOAD THE SVG
  Dim svgDocument = Svg.SvgDocument.Open("C:\users\admin\Pictures\jcss.svg")
  svgDocument.ShapeRendering = SvgShapeRendering.Auto

  Dim bmp As Bitmap = svgDocument.Draw(650, 700)
  PictureBox2.Image = bmp

'Draggable SVG map.
    Private Sub PictureBox2_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox2.MouseDown
        StartPoint = PictureBox2.PointToScreen(New Point(e.X, e.Y))
        IsDragging = True
    End Sub

    Private Sub PictureBox2_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox2.MouseMove
        If IsDragging Then
            Dim EndPoint As Point = PictureBox2.PointToScreen(New Point(e.X, e.Y))
            PictureBox2.Left += (EndPoint.X - StartPoint.X)
            PictureBox2.Top += (EndPoint.Y - StartPoint.Y)
            StartPoint = EndPoint
        End If
    End Sub

'Used for Zooming and Dragging
    Dim SF As String = 1

    Private IsDragging As Boolean = False
    Private StartPoint As Point

    Private Sub PictureBox2_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox2.MouseUp
        IsDragging = False
    End Sub

'ZOOM THE SVG.

  If e.Delta > 0 Then
            SF = SF + 0.1
            Dim svgDocument = Svg.SvgDocument.Open("C:\users\admin\Pictures\jcss.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\jcss.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

我知道地图的width450 和height530。我还知道,当根本不缩放时,地图的左经度是123.658963,它的上纬度是45.523885,它的右经度是145.820743,它的下纬度是24.217586。此信息包含在我下载 SVG 地图的源代码中。

SVG 地图可在此处下载:下载 SVG (G. Drive)

考虑到缩放因子,我是否可以编写任何函数,可以将经度和纬度转换为带有墨卡托投影的地图上的一个点?我已经为此工作了几个月,但我从未成功过。

编辑:

我发现我可以调整MapWidthandMapHeight来考虑缩放。如果不考虑缩放,该功能仍然不起作用。

标签: .netvb.netsvgmaps

解决方案


推荐阅读