Общие формулы проекции Mercator для Google Maps не работают правильно

StackOverflow https://stackoverflow.com/questions/2656580

Вопрос

Я создаю сервер наложения плитки для Google Maps в C # и нашел несколько различных примеров кода для расчета Y из широты. После того, как они работали в целом, я начал замечать определенные случаи, когда накладки не были правильно подкладываться. Чтобы проверить это, я сделал тестовый жгут для сравнения Google Mark's Mercator Lattoy Conversion против формул, которые я нашел в Интернете. Как вы можете видеть ниже, они не совпадают в определенных случаях.

Дело 1

Увеличивается: проблема наиболее очевидна, когда уменьшается. Закрыть, проблема едва видна.

Случай № 2.

Точка близость к вершине и нижней части границ просмотра: проблема хуже в середине рассматриваемых границ и становится лучше по отношению к краям. Это поведение может отрицать поведение случая # 1

Тест:

Я создал страницу Google Maps для отображения красных линий, использующих API Google Map API, встроенный в Convision Mercator, и накладывает это изображение с помощью справочного кода для преобразования Mercator. Эти преобразования представлены как черные линии. Сравните разницу.

Результаты:Equator 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/mercatorComprison%20-%20North%20ZOOMED%20OUT%20-%20TOPANDBOTTOM.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 Maps Побочный код клиента:

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

Код Server Side:

Плиточный резак: 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 # внедрение конвертации координат проекта Mercator?

Спасибо!

Это было полезно?

Решение

Спасибо всем за ваши предложения и помощь.

То, что я в конечном итоге узнал, что это не формула или техническая проблема, я считаю, что это проблема методологии.

Вы не можете определить область просмотра в формате NAT / LNG и ожидаю, чтобы заполнить его соответствующим проекциям Mercator. Вот где происходит искажение. Вместо этого вы должны определить правильную просмотр поле в Mercator, а также проект Mercator.

Делать, что я смог правильно сопоставить с Google Maps.

Другие советы

Возможно, вам придется создать несколько баллов вдоль долготой, чтобы точки были проецированы в корректно по широте. В ваших примерах вы действительно проецируете только два очка в начале и конце строки и подключив два.

Проблема будет более очевидной в экваторе из-за более значительной кривизны земли. Это будет меньше, когда увеличено по той же причине.

Посмотри на http://code.google.com/apis/maps/documentation/overlays.html#great_circles.

Попробуйте создать свой Google Polylines с геодическим параметром, чтобы увидеть, имеет ли это значение. Я думаю, что это добавляет очки вдоль линии и проекты их автоматически:

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. (Другие ссылки / объяснения)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top