6

C#でGoogleマップ用のタイルオーバーレイサーバーを構築していますが、LatitudeからYを計算するためのいくつかの異なるコード例を見つけました。それらを一般的に機能させた後、私はオーバーレイが適切に整列していない特定のケースに気づき始めました。これをテストするために、テストハーネスを作成して、GoogleMapのメルカトルLatToY変換をオンラインで見つけた数式と比較しました。以下に示すように、特定のケースでは一致しません。

ケース#1

ズームアウト:この問題は、ズームアウトしたときに最も顕著になります。間近で見ると、問題はほとんど見えません。

ケース#2

表示境界の上下に近接する:問題は表示境界の中央で悪化し、端に向かって良くなります。この動作は、ケース#1の動作を無効にする可能性があります

テスト:

Google Map APIに組み込まれているメルカトル図法変換を使用して赤い線を表示するGoogleマップページを作成し、メルカトル図法変換を行うための参照コードを使用してこれを画像でオーバーレイしました。これらの変換は黒い線で表されます。違いを比較します。

結果: 赤道http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png North ZoomedOuthttp://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out。 png

一番上の行と一番下の行を確認してください: North Top&Bottom Example http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out%20-%20TopAndBottom.png

ズームインすると、問題は視覚的に大きくなりますが、数値的に小さくなります 。alt text http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Midway.png

そして、画面の向きに関係なく、ズームレベルを近づけるとほとんど消えます。 代替テキストhttp://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20In.png

コード:

Googleマップのクライアントサイドコード:

            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));
        }

サーバーサイドコード:

タイルカッター: 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#実装がありますか?

ありがとう!

4

2 に答える 2

1

提案と支援をありがとうございました。

私が最終的に見つけたのは、それは公式や技術的な問題ではなく、方法論の問題だと思います。

表示領域をLat/Lng形式で定義することはできず、適切なメルカトル図法を使用することを期待できます。ここで歪みが発生します。代わりに、メルカトル図法で正しい表示ボックスを定義し、メルカトル図法を投影する必要があります。

そうすることで、Googleマップと正しく一致させることができました。

于 2010-05-04T16:09:53.723 に答える
0

ポイントを緯度に沿って正確に投影するには、経度に沿っていくつかのポイントを作成する必要がある場合があります。あなたの例では、実際には線の始点と終点の2つのポイントを投影し、2つを接続しています。

地球のより重要な湾曲のために、問題は赤道でより明白になります。同じ理由でズームインすると少なくなります。

http://code.google.com/apis/maps/documentation/overlays.html#Great_Circlesをご覧ください

geodsicパラメータを使用してGoogleポリラインを作成してみて、これが違いを生むかどうかを確認してください。これにより、線に沿ってポイントが追加され、自動的に投影されると思います。

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(その他のリンク/説明)

于 2010-05-03T08:54:35.087 に答える