Хранение значений Lat Lng в MySQL с использованием типа пространственной точки - PullRequest
36 голосов
/ 14 февраля 2011

Используемые технологии: MySQL 5.1 и PHP 5.3

Я просто проектирую новую базу данных для сайта, который пишу. Я смотрю на лучший способ хранения значений Lat и Lng.

В прошлом я использовал DECIMAL и выбирал PHP / MySQL в форме:

SQRT(POW(69.1 * (fld_lat - ( $lat )), 2) + POW(69.1 * (($lon) - fld_lon) * COS(fld_lat / 57.3 ), 2 )) AS distance

для поиска ближайших подходящих мест.

Начинаю читать больше о новых технологиях. Мне интересно, стоит ли мне использовать Spatial Extensions. http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html

Хотя информация довольно тонкая на местах, и у нее возник вопрос о том, как хранить данные. Вместо того чтобы использовать DECIMAL, я бы теперь использовал POINT как тип данных?

Кроме того, будучи сохраненным в виде POINT, легко получить значения Lat Lng из него на случай, если я захочу нанести его на карту, или я должен также дополнительно сохранить значения lat Lngs как DECIMALS?

Я знаю, что мне следует использовать PostGIS, так как большинство постов говорят, что я просто не хочу изучать новую БД!

Продолжение

Я играл с новым типом POINT. Мне удалось добавить значения Lat Lng, используя следующее:

INSERT INTO spatialTable (placeName, geoPoint) VALUES( "London School of Economics", GeomFromText( 'POINT(51.514 -0.1167)' ));

Затем я могу получить значения Lat и Lng из БД, используя:

SELECT X(geoPoint), Y(geoPoint) FROM spatialTable;

Это все выглядит хорошо, однако вычисление для расстояния - это бит, который мне нужно решить. Очевидно, MySQL имеет заполнитель для функции расстояния, но некоторое время не будет выпущен. В нескольких сообщениях я обнаружил, что мне нужно сделать что-то подобное ниже, однако я думаю, что мой код немного неправильный:

SELECT
 placeName,
 ROUND(GLength(
  LineStringFromWKB(
   LineString(
    geoPoint, 
    GeomFromText('POINT(52.5177, -0.0968)')
  )
  )
))
AS distance
FROM spatialTable
ORDER BY distance ASC;

В этом примере geoPoint - это ТОЧКА, введенная в БД с помощью INSERT выше.

GeomFromText('POINT(52.5177, -0.0968)' - значение Lat Lng, от которого я хочу вычислить расстояние.

Дополнительные наблюдения

Довольно глупо, что я просто вставил часть раунда SQL, не задумываясь. Сняв это, я получаю:

SELECT
placeName,
(GLength(
LineStringFromWKB(
  LineString(
    geoPoint, 
    GeomFromText('POINT(51.5177 -0.0968)')
  )
 )
))
AS distance
FROM spatialTable
ORDER BY distance ASC

Что, кажется, дает мне правильные расстояния, которые мне нужны.

Полагаю, единственное, что в настоящее время нуждается в ответе, - это какие-либо мысли о том, просто ли я усложняю себе жизнь, используя Spatial сейчас или сам себе - будущее ...

Ответы [ 4 ]

8 голосов
/ 22 апреля 2012

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

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

Худший пример, который меня поразил, это то, что если у вас есть многоугольник, представляющий Японию, и вы спрашиваете, какие места в Японии, Владивосток попадает в список!

Oracle и PostGIS не имеют этой проблемы. Я ожидаю, что MSSQL этого не делает, и любая база данных Java использует JTS, так как ее движок этого не делает. Geospatial Good. MySQL Geospatial Bad.

Просто прочитайте здесь Как вы используете пространственные запросы MySQL для поиска всех записей в радиусе X? , которые зафиксированы в 5.6.1.

Hoorah!

1 голос
/ 21 мая 2015

Если вы можете добавить некоторый дополнительный код в свой бэкэнд, используйте Geohash.

Он кодирует координату в строку таким образом, что префиксы обозначают более широкую область.Чем длиннее ваша строка, тем выше точность.

И она имеет привязки для многих языков.

http://en.wikipedia.org/wiki/Geohash https://www.elastic.co/guide/en/elasticsearch/guide/current/geohashes.html

1 голос
/ 17 апреля 2011

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

1 голос
/ 09 марта 2011

Mysql GIS yagni:

Если у вас нет опыта работы с ГИС, изучение пространственных расширений практически равносильно изучению новой базы данных, плюс немного математики и множество сокращений. Карты, проекции, srids, форматы ... Нужно ли вам учиться всему этому, чтобы рассчитывать расстояния между точками с заданным определенным широтным / длинным: вероятно, нет, будете ли вы интегрировать данные ГИС третьих сторон или работать с чем-то более сложным, чем точки, систему координат вы будете использовать?

Возвращаясь к yagni: делайте все как можно проще, в этом случае реализуйте свой код на php или с простым SQL. Как только вы достигнете барьера и решите, что вам нужно пространственное пространство, ознакомьтесь с системой ГИС, системами координат, проектами и соглашениями.

К тому времени вы, вероятно, захотите PostGIS.

...