Преобразуйте long/lat в пиксель x/y на данном изображении

У меня есть городская карта Москвы. Мы изменили изображение Google Maps с некоторыми артистическими элементами, но отношение между координатами GPS и пикселями остается тем же.

Проблема: Как я преобразовываю координаты GPS из различных точек данных, которые мы имеем в пиксельные координаты в изображении?

Идеально я могу сделать это в JavaScript, но PHP был бы в порядке.


Я знаю, что на мелких масштабах (например, в городских масштабах) это для создания достаточно просто (необходимо изучить, какие географические координаты имеют один из углов изображения, затем для изучения "цены" одного пикселя в географических координатах на изображении на ВОЛЕ осей и OY отдельно).

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

Как решить проблему в масштабах страны?


Обновление:

Я не использую Google Maps API, я имею только: географические координаты объекта (они из карт Google), у меня все еще есть на моем сайте простое изображение *. gif, в котором я должен потянуть точку соответствующие географические координаты.

64
задан Chris Moschini 11 August 2015 в 21:52
поделиться

7 ответов

Ключ ко всему этому - понимание картографических проекций . Как указывали другие, причиной искажения является то, что сферическая (или, точнее, эллипсоидальная) Земля проецируется на плоскость.

Чтобы достичь своей цели, вы сначала должны знать две вещи о своих данных:

  1. Проекцию, в которой находятся ваши карты. Если они получены исключительно из Google Maps , то, скорее всего, они с использованием сферической проекции Меркатора .
  2. Географическая система координат, которую используют ваши координаты широты и долготы. Это может быть разным, потому что есть разные способы определения широты и долготы на земном шаре. Наиболее распространенным GCS, используемым в большинстве веб-картографических приложений и для GPS, является WGS84 .

Я предполагаю, что ваши данные находятся в этих системах координат.

Сферическая проекция Меркатора определяет пару координат в метрах для поверхности Земли. Это означает, что для каждой координаты широта / долгота существует соответствующая координата метр / метр. Это позволяет выполнить преобразование, используя следующую процедуру:

  1. Найдите широту / длину углов изображения WGS84.
  2. Преобразуйте широту / долготу WGS в сферическую проекцию Меркатора. Существуют инструменты преобразования, мне больше всего нравится использовать инструмент cs2cs, который является частью проекта PROJ4 .
  3. Вы можете безопасно выполнить простое линейное преобразование для преобразования между точками на изображении и точками на Земле в сферической проекции Меркатора и обратно.

Чтобы перейти от точки WGS84 к пикселю на изображении, выполните следующие действия:

  1. Проецируйте широту / долготу на сферический Меркатор. Это можно сделать с помощью библиотеки proj4js.
  2. Преобразование сферической координаты Меркатора в пиксельную координату изображения, используя обнаруженную выше линейную зависимость.

Вы можете использовать библиотеку 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
70
ответ дан 24 November 2019 в 15:52
поделиться

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

http://www.johndcook.com/blog / 2009/04/27 / преобразование миль в градусы долготы или широты /

3
ответ дан 24 November 2019 в 15:52
поделиться

Вы можете взглянуть на код , который используется в gheat , он перенесен с js на python.

7
ответ дан 24 November 2019 в 15:52
поделиться

Вам нужны формулы для преобразования широты и долготы в прямоугольные координаты. Есть множество вариантов на выбор, и каждый будет искажать карту по-своему. У Wolfram MathWorld хорошая коллекция:

http://mathworld.wolfram.com/MapProjection.html

Перейдите по ссылкам «См. Также».

3
ответ дан 24 November 2019 в 15:52
поделиться

Итак, вы хотите взять координаты широты и долготы и узнать координаты пикселей на вашем изображении этого места?

Основной класс 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

8
ответ дан 24 November 2019 в 15:52
поделиться

Перевод, к которому вы обращаетесь, имеет отношение к Проекция карты , то есть как сферическая поверхность нашего мира преобразуется в двухмерную визуализацию. Есть несколько способов (проекций) визуализировать мир на двухмерной поверхности.

Если на ваших картах используется только определенная проекция (популярна Меркатор ), вы сможете найти уравнения, некоторый пример кода и / или некоторую библиотеку (например, одно решение Меркатора - ] Преобразование широты и долготы в координаты X / Y . Если это не поможет, я уверен, вы сможете найти другие образцы - https://stackoverflow.com/search?q=mercator . Если ваши изображения не карты, использующие проекцию Меркатора, вам необходимо определить, какую проекцию он использует, чтобы найти правильные уравнения перевода.

Если вы пытаетесь поддерживать несколько проекций карты ( вы хотите поддерживать множество различных карт, использующих разные проекции), тогда вы определенно захотите использовать такую ​​библиотеку, как PROJ.4 , но опять же, я не уверен, что вы найдете для Javascript или PHP.

5
ответ дан 24 November 2019 в 15:52
поделиться

Вам нужно будет реализовать проекцию 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));
    }
}

Источник:

http://code.google.com/p/geographic-dot-net/source/browse/trunk/GeographicDotNet/GeographicDotNet/Projection/GoogleMapsAPIProjection.cs

16
ответ дан 24 November 2019 в 15:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: