首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >谷歌地图中常用的Mercator投影公式

谷歌地图中常用的Mercator投影公式
EN

Stack Overflow用户
提问于 2010-04-16 23:20:02
回答 2查看 4.2K关注 0票数 6

我正在为C#中的谷歌地图构建一个Tile覆盖服务器,并找到了几个从纬度计算Y的不同代码示例。在让他们开始工作后,我开始注意到某些情况下,覆盖没有正确地排列。为了测试这一点,我做了一个测试工具,将Google的Mercator LatToY转换与我在网上找到的公式进行比较。正如您在下面看到的,它们在某些情况下并不匹配。

案例#1

放大:这个问题在放大时最明显。近距离来看,这个问题几乎看不出来。

案例#2

接近顶部和底部的观看界限:问题是更严重的中间观看边界,并得到更好的边缘。这种行为可以否定案例1的行为。

测试:

我创建了一个google地图页面,使用Google Map API内置的Mercator转换来显示红线,并使用参考代码进行Mercator转换。这些转换被表示为黑线。比较一下差别。

结果:赤道http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png 北方放大http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out.png

查看最上面和最底部的行:北顶&下例http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out%20-%20TopAndBottom.png

当您放大时,问题会变得更大,但在数字上却更小:alt文本http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Midway.png

它几乎消失在更近的缩放水平,无论屏幕的方向。alt文本http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20In.png

“守则”:

谷歌地图客户端代码:

代码语言:javascript
复制
            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));
        }

服务器端代码:

瓷砖刀具:切割机 OpenStreetMap Wiki:http://wiki.openstreetmap.org/wiki/Mercator

代码语言:javascript
复制
 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#实现墨卡托项目坐标转换?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-05-04 16:09:53

谢谢大家的建议和帮助。

我最终发现,这不是一个公式或技术问题,我认为这是一个方法论问题。

您不能定义Lat/Lng格式的查看区域,而需要使用适当的Mercator投影来填充它。这就是扭曲发生的地方。相反,您必须在Mercator和中定义正确的查看框。

这样做,我就能够正确地匹配谷歌地图。

票数 1
EN

Stack Overflow用户

发布于 2010-05-03 08:54:35

你可能需要在经度线上创建几个点,这样才能使这些点沿着纬度进行贴切的投影。在您的例子中,您实际上只是在直线的开始和结束处突出两个点,并将两者连接起来。

由于地球的弯曲程度更大,这个问题在赤道会更加明显。由于同样的原因,如果放大,它会更少。

看看圆圈

尝试使用geodsic参数创建您的Google,以查看这是否会产生影响。我认为这会在这条线上增加点,并自动投影它们:

代码语言:javascript
复制
var lat = 0;
var polyOptions = {geodesic:true};
for (lat = -80; lat <= 80; lat += 5) {
    map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2, polyOptions));
    map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2, polyOptions));
}

我不得不读到这一点,因为我所有的距离测量在OpenLayers中都是错误的,原因类似:http://geographika.co.uk/watch-out-for-openlayer-distances (更多的链接/解释)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2656580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档