我正在用 C# 为 Google map 构建一个 Tile Overlay 服务器,并找到了几个不同的代码示例来从 Latitude 计算 Y。在让它们正常工作后,我开始注意到某些情况下叠加层没有正确对齐。为了对此进行测试,我制作了一个测试工具来比较 Google Map 的 Mercator LatToY 转换与我在网上找到的公式。如下所示,它们在某些情况下不匹配。
案例 #1
Zoomed Out: The problem is most evident when zoomed out. Up close, the problem is barely visible.
案例#2
Point Proximity to Top & Bottom of viewing bounds: The problem is worse in the middle of the viewing bounds, and gets better towards the edges. This behavior can negate the behavior of Case #1
测试:
I created a google maps page to display red lines using the Google Map API's built in Mercator conversion, and overlay this with an image using the reference code for doing Mercator conversion. These conversions are represented as black lines. Compare the difference.
结果: Equator http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png North Zoomed Out http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out.png
当您放大时,问题在视觉上变大但在数值上变小: alt text http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Midway.png
无论屏幕方向如何,在更近的缩放级别上它几乎都消失了。 alt text http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20In.png
代码:
Google map 客户端代码:
var lat = 0;
for (lat = -80; lat <= 80; lat += 5) {
map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2));
map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2));
}
服务器端代码:
Tile Cutter : http://mapki.com/wiki/Tile_Cutter
OpenStreetMap Wiki : http://wiki.openstreetmap.org/wiki/Mercator
protected override void ImageOverlay_ComposeImage(ref Bitmap ZipCodeBitMap)
{
Graphics LinesGraphic = Graphics.FromImage(ZipCodeBitMap);
Int32 MapWidth = Convert.ToInt32(Math.Pow(2, zoom) * 255);
Point Offset =
Cartographer.Mercator2.toZoomedPixelCoords(North, West, zoom);
TrimPoint(ref Offset, MapWidth);
for (Double lat = -80; lat <= 80; lat += 5)
{
Point StartPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -179, zoom);
Point EndPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -1, zoom);
TrimPoint(ref StartPoint, MapWidth);
TrimPoint(ref EndPoint, MapWidth);
StartPoint.X = StartPoint.X - Offset.X;
EndPoint.X = EndPoint.X - Offset.X;
StartPoint.Y = StartPoint.Y - Offset.Y;
EndPoint.Y = EndPoint.Y - Offset.Y;
LinesGraphic.DrawLine(new Pen(Color.Black, 2),
StartPoint.X,
StartPoint.Y,
EndPoint.X,
EndPoint.Y);
LinesGraphic.DrawString(
lat.ToString(),
new Font("Verdana", 10),
new SolidBrush(Color.Black),
new Point(
Convert.ToInt32((width / 3.0) * 2.0),
StartPoint.Y));
}
}
protected void TrimPoint(ref Point point, Int32 MapWidth)
{
point.X = Math.Max(point.X, 0);
point.X = Math.Min(point.X, MapWidth - 1);
point.Y = Math.Max(point.Y, 0);
point.Y = Math.Min(point.Y, MapWidth - 1);
}
那么,有人遇到过这种情况吗?敢问,解决了吗?或者只是有一个更好的墨卡托项目坐标转换的 C# 实现?
谢谢!
最佳答案
感谢大家的建议和帮助。
我最终发现这不是公式或技术问题,我认为这是方法论问题。
您不能以 Lat/Lng 格式定义查看区域,并期望用适当的墨卡托投影填充它。这就是失真发生的地方。相反,您必须在墨卡托中定义正确的查看框,并投影墨卡托。
这样我就能够正确匹配 Google map 。
关于c# - Google map 的常见墨卡托投影公式无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2656580/