0

我正在尝试使用 Bing Maps WPF 控件从虚构的游戏世界地图的图像中渲染自定义地图图块,但我还需要根据原始世界图像在地图上绘制 X、Y 值(有点像 in-世界 GPS)。

图像是 5720x5720,我已经在工作(在不同的应用程序中)一个手动裁剪、缩放和重绘图像部分并在 PictureBox 中绘制 pixelX 和 pixelY 坐标的函数。我想使用地图控件获得相同的功能。

我使用这个 Photoshop 插件从原始自定义图像中切割瓷砖(类似于谷歌地图的 maptiler) https://github.com/bramus/photoshop-google-maps-tile-cutter/

问题是我知道要从原始图像中绘制的 X、Y 值,但我不太确定如何计算纬度/经度以在自定义平铺系统中绘制一个点。

<m:Map Name="Map">
        <m:Map.Mode>
            <!-- set empty map mode, i.e. remove default map layer -->
            <m:MercatorMode/>
        </m:Map.Mode>
        <local:MyTileLayer UriFormat="file:///C:/map_tiles/{z}_{x}_{y}.jpg"/>
</m:Map>

使用自定义地图图块,地图显示效果很好,一切看起来都很好。我发现这个链接提供了一个在 TileSystem 中将 PixelXY 转换为 LatLong 的类,但它们都是针对现实世界点的。

https://msdn.microsoft.com/en-us/library/bb259689.aspx

我的自定义地图图块实际上是用于游戏的虚构地图,因此我认为在我的情况下不需要投影和地球曲率计算。

如果我只知道原始图像的 X、Y 像素坐标,我该如何在 Bing Maps WPF 控件中准确地绘制一个点?

4

2 回答 2

0

如果您使用 MapTiler ( http://www.maptiler.com ) 创建图块,您有两种方法可以实现您想要的:

A) 将您的游戏地图映射到具有纬度/经度坐标的人造世界

在这种情况下,您会将世界坐标映射到您的像素坐标。必须以正确的方式准备瓷砖,与现实世界地图的瓷砖相同。

要使用 MapTiler 创建图块,您应该按照以下步骤操作:

  1. 第一步选择“墨卡托瓷砖”
  2. 放入您的图像文件
  3. 在“坐标系”对话框的下拉列表中选择“Web mercator (EPSG:3857)” - 它是整个世界的方形图像,您不想让它变形。
  4. 在“地理位置”对话框中选择“边界框(西南东南北)”并复制并粘贴输入世界坐标:“-20037508.342789244 -20037508.342789244 20037508.342789244 20037508.342789244”
  5. 渲染瓷砖

使用这种方法,您可以在 Bing Maps WPF 控件中加载图块,并使用纬度/经度坐标定位标记或其他数据。点 [0,0] 将成为图像的中心,您可以适当地计算其他纬度/经度坐标。请参阅此页面和页面上的源代码: http ://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ 页面中嵌入的 globalmaptiles.py 代码有不同的语言版本,包括 C# ( .cs)如果你需要它。它已被其他人从我们的代码中移植。

B) 停留在栅格坐标中

另一种方法 - 您在输入文件的原始栅格坐标中创建地图切片。不涉及纬度/经度,坐标系以像素为单位,您也可以在像素坐标中绘制标记和多边形。MapTiler 在 Leaflet 和 OpenLayers 中为您提供示例 JavaScript 查看器。您必须自己修补其他查看器以使用像素坐标。要生成图块,只需选择“光栅图块” - 如本教程所示:http: //youtu.be/9iYKmRsGoxg?list=PLGHe6Moaz52PiQd1mO- S9QrCjqSn1v -ay 我希望用您的 Photoshop 插件制作的图块将类似于光栅使用 MapTiler 制作的坐标。

于 2015-02-02T17:16:28.990 回答
0

鉴于您的 5720x5720px 地图图像涵盖经度 = -180..180纬度 = -85.0511..85.0511的标准 Bing 地图(或谷歌地图或 OpenStreetMap)坐标范围,以下方法将从图像像素坐标转换为纬度/经度根据墨卡托投影:

public static void PixelXYToLatLon(
    double pixelX, double pixelY, out double latitude, out double longitude)
{
    var imageSize = 5720d;
    var maxLatitude = 85.05112878; // = Math.Atan(Math.Sinh(Math.PI)) / Math.PI * 180d;
    var y = (0.5 - pixelY / imageSize) * (2d * maxLatitude);
    latitude = Math.Atan(Math.Sinh(y * Math.PI / 180d)) / Math.PI * 180d;
    longitude = (pixelX / imageSize - 0.5) * 360d;
}

imageSize 变量当然也可能是一个方法参数。

于 2015-02-01T23:34:16.220 回答