У меня есть городская карта Москвы. Мы изменили изображение Google Maps с некоторыми артистическими элементами, но отношение между координатами GPS и пикселями остается тем же.
Проблема: Как я преобразовываю координаты GPS из различных точек данных, которые мы имеем в пиксельные координаты в изображении?
Идеально я могу сделать это в JavaScript, но PHP был бы в порядке.
Я знаю, что на мелких масштабах (например, в городских масштабах) это для создания достаточно просто (необходимо изучить, какие географические координаты имеют один из углов изображения, затем для изучения "цены" одного пикселя в географических координатах на изображении на ВОЛЕ осей и OY отдельно).
Но в больших масштабах (масштаб страны) "цена" одного пикселя будет не константой, и будет варьироваться достаточно сильно, и метод, описанный выше, не может быть применен.
Как решить проблему в масштабах страны?
Обновление:
Я не использую Google Maps API, я имею только: географические координаты объекта (они из карт Google), у меня все еще есть на моем сайте простое изображение *. gif, в котором я должен потянуть точку соответствующие географические координаты.
Ключ ко всему этому - понимание картографических проекций . Как указывали другие, причиной искажения является то, что сферическая (или, точнее, эллипсоидальная) Земля проецируется на плоскость.
Чтобы достичь своей цели, вы сначала должны знать две вещи о своих данных:
Я предполагаю, что ваши данные находятся в этих системах координат.
Сферическая проекция Меркатора определяет пару координат в метрах для поверхности Земли. Это означает, что для каждой координаты широта / долгота существует соответствующая координата метр / метр. Это позволяет выполнить преобразование, используя следующую процедуру:
Чтобы перейти от точки WGS84 к пикселю на изображении, выполните следующие действия:
Вы можете использовать библиотеку proj4js следующим образом:
// include the library
<script src="lib/proj4js-combined.js"></script> //adjust the path for your server
//or else use the compressed version
// creating source and destination Proj4js objects
// once initialized, these may be re-used as often as needed
var source = new Proj4js.Proj('EPSG:4326'); //source coordinates will be in Longitude/Latitude, WGS84
var dest = new Proj4js.Proj('EPSG:3785'); //destination coordinates in meters, global spherical mercators projection, see http://spatialreference.org/ref/epsg/3785/
// transforming point coordinates
var p = new Proj4js.Point(-76.0,45.0); //any object will do as long as it has 'x' and 'y' properties
Proj4js.transform(source, dest, p); //do the transformation. x and y are modified in place
//p.x and p.y are now EPSG:3785 in meters
Если предполагается, что каждый пиксель находится в одной и той же области, то следующая статья о преобразовании расстояний в координаты долготы / широты может быть вам полезна:
http://www.johndcook.com/blog / 2009/04/27 / преобразование миль в градусы долготы или широты /
Вы можете взглянуть на код , который используется в gheat , он перенесен с js на python.
Вам нужны формулы для преобразования широты и долготы в прямоугольные координаты. Есть множество вариантов на выбор, и каждый будет искажать карту по-своему. У Wolfram MathWorld хорошая коллекция:
http://mathworld.wolfram.com/MapProjection.html
Перейдите по ссылкам «См. Также».
Итак, вы хотите взять координаты широты и долготы и узнать координаты пикселей на вашем изображении этого места?
Основной класс GMap2 обеспечивает преобразование в / из пикселя на отображаемой карте и координаты широты / долготы:
Gmap2.fromLatLngToContainerPixel(latlng)
Например:
var gmap2 = new GMap2(document.getElementById("map_canvas"));
var geocoder = new GClientGeocoder();
geocoder.getLatLng( "1600 Pennsylvania Avenue NW Washington, D.C. 20500",
function( latlng ) {
var pixel_coords = gmap2.fromLatLngToContainerPixel(latlng);
window.alert( "The White House is at pixel coordinates (" +
pixel_coodrs.x + ", " + pixel_coords.y + ") on the " +
"map image shown on this page." );
}
);
Итак, если предположить, что ваше изображение карты представляет собой снимок экрана отображения Google Map, тогда это даст вам правильную координату пикселя на это изображение широты и долготы.
Ситуация усложняется, если вы захватываете изображения плиток и сами соединяете их вместе, поскольку область полного набора плиток будет лежать за пределами области отображаемой карты.
В этом случае вам нужно использовать левое и верхнее значения верхнего левого тайла изображения в качестве смещения от координат, которые дает fromLatLngToContainerPixel (latlng: GLatLng), вычитая левую координату из координаты x и сверху от координаты y. Итак, если верхнее левое изображение расположено в (-50, -122) (слева, вверху), а fromLatLngToContainerPixel () сообщает вам, что широта / долгота находится в пиксельной координате (150, 320), то на изображении, сшитом вместе из плитки, истинное положение координаты находится в (150 - (-50), 320 - (-122)), что составляет (200, 442).
Также возможно, что аналогичная функция преобразования координат GMap2:
GMap2.fromLatLngToDivPixel(latlng:GLatLng)
даст вам правильное преобразование широты / долготы в пиксель для случая сшитых плиток - я не тестировал это и не на 100% ясен из Документы API.
Подробнее см. Здесь: http://code.google.com/apis/maps/documentation/reference.html#GMap2.Methods.Coordinate-Transformations
Перевод, к которому вы обращаетесь, имеет отношение к Проекция карты , то есть как сферическая поверхность нашего мира преобразуется в двухмерную визуализацию. Есть несколько способов (проекций) визуализировать мир на двухмерной поверхности.
Если на ваших картах используется только определенная проекция (популярна Меркатор ), вы сможете найти уравнения, некоторый пример кода и / или некоторую библиотеку (например, одно решение Меркатора - ] Преобразование широты и долготы в координаты X / Y . Если это не поможет, я уверен, вы сможете найти другие образцы - https://stackoverflow.com/search?q=mercator . Если ваши изображения не карты, использующие проекцию Меркатора, вам необходимо определить, какую проекцию он использует, чтобы найти правильные уравнения перевода.
Если вы пытаетесь поддерживать несколько проекций карты ( вы хотите поддерживать множество различных карт, использующих разные проекции), тогда вы определенно захотите использовать такую библиотеку, как PROJ.4 , но опять же, я не уверен, что вы найдете для Javascript или PHP.
Вам нужно будет реализовать проекцию API Карт Google на своем языке. У меня есть исходный код C # для этого:
public class GoogleMapsAPIProjection
{
private readonly double PixelTileSize = 256d;
private readonly double DegreesToRadiansRatio = 180d / Math.PI;
private readonly double RadiansToDegreesRatio = Math.PI / 180d;
private readonly PointF PixelGlobeCenter;
private readonly double XPixelsToDegreesRatio;
private readonly double YPixelsToRadiansRatio;
public GoogleMapsAPIProjection(double zoomLevel)
{
var pixelGlobeSize = this.PixelTileSize * Math.Pow(2d, zoomLevel);
this.XPixelsToDegreesRatio = pixelGlobeSize / 360d;
this.YPixelsToRadiansRatio = pixelGlobeSize / (2d * Math.PI);
var halfPixelGlobeSize = Convert.ToSingle(pixelGlobeSize / 2d);
this.PixelGlobeCenter = new PointF(
halfPixelGlobeSize, halfPixelGlobeSize);
}
public PointF FromCoordinatesToPixel(PointF coordinates)
{
var x = Math.Round(this.PixelGlobeCenter.X
+ (coordinates.X * this.XPixelsToDegreesRatio));
var f = Math.Min(
Math.Max(
Math.Sin(coordinates.Y * RadiansToDegreesRatio),
-0.9999d),
0.9999d);
var y = Math.Round(this.PixelGlobeCenter.Y + .5d *
Math.Log((1d + f) / (1d - f)) * -this.YPixelsToRadiansRatio);
return new PointF(Convert.ToSingle(x), Convert.ToSingle(y));
}
public PointF FromPixelToCoordinates(PointF pixel)
{
var longitude = (pixel.X - this.PixelGlobeCenter.X) /
this.XPixelsToDegreesRatio;
var latitude = (2 * Math.Atan(Math.Exp(
(pixel.Y - this.PixelGlobeCenter.Y) / -this.YPixelsToRadiansRatio))
- Math.PI / 2) * DegreesToRadiansRatio;
return new PointF(
Convert.ToSingle(latitude),
Convert.ToSingle(longitude));
}
}
Источник: