Я создаю сервер Наложения Мозаики для карт Google в C# и нашел несколько различных примеров кода для вычисления Y от Широты. После того, чтобы заставлять их работать в целом, я начал замечать определенные случаи, где оверлейные программы не выстраивались в линию правильно. Для тестирования этого я сделал тестовую обвязку для сравнения Меркаторского преобразования LatToY Google Map с формулами, которые я нашел онлайн. Как Вы видите ниже, они не соответствуют в определенных случаях.
Случай № 1
Уменьшенный: проблема является самой очевидной при уменьшении. Близко проблема едва видима.
Случай № 2
Близость точки к Вершине и Нижней части просмотра границ: проблема хуже посреди границ просмотра и поправляется к краям. Это поведение может инвертировать поведение Случая № 1
Тест:
Я создал страницу карт Google для отображения, красные строки с помощью API Google Map создал в Меркаторском преобразовании и накладывают это с изображением с помощью кода ссылки для того, чтобы сделать Меркаторское преобразование. Эти преобразования представлены как черные линии. Сравните различие.
Результаты: Экватор http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png Север, уменьшенный http://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
Проблема становится визуально больше, но численно меньший, поскольку Вы увеличиваете масштаб: сопроводительный текст http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Midway.png
И все это, но исчезает на более близких уровнях масштабирования, независимо от экранной ориентации. сопроводительный текст 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));
}
Серверный код:
Резак мозаики: 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# Меркаторского координатного преобразования Проекта?
Спасибо!
Спасибо всем за ваши предложения и помощь.
В конце концов я обнаружил, что это не формула или техническая проблема, я считаю, что это проблема методологии.
Вы не можете определить область просмотра в формате широты / долготы и ожидать, что заполните ее соответствующими проекциями Меркатора. Вот где происходит искажение. Вместо этого вам нужно определить правильное окно просмотра в Меркаторе и спроектировать Меркатор.
Благодаря этому я смог правильно сопоставить с картами Google.
Возможно, вам придется создать несколько точек по долготе, чтобы точки проецировались правильно по широте. В ваших примерах вы действительно проецируете только две точки в начале и в конце линии и соединяете их.
Проблема будет более очевидной на экваторе из-за более значительной кривизны Земли. При увеличении будет меньше по той же причине.
Взгляните на http://code.google.com/apis/maps/documentation/overlays.html#Great_Circles
Попробуйте создать свои полилинии Google с параметром geodsic, чтобы увидеть, имеет ли это значение . Я думаю, что это добавляет точки вдоль линии и проецирует их автоматически:
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-distance (дополнительные ссылки / объяснения)