Вопрос по mysql – Посмотрите, попадает ли lat / long в многоугольник, используя mysql

14

У меня есть созданная таблица ниже

CREATE TABLE geom (g GEOMETRY);

и вставили много строк, пример ниже:

INSERT INTO geom (g)
VALUES(PolygonFromText('POLYGON((
9.190586853 45.464518970,
9.190602686 45.463993916,
9.191572471 45.464001929,
9.191613325 45.463884676,
9.192136130 45.463880767,
9.192111509 45.464095594,
9.192427961 45.464117804,
9.192417811 45.464112862,
9.192509035 45.464225851,
9.192493139 45.464371079,
9.192448471 45.464439002,
9.192387444 45.464477861,
9.192051402 45.464483037,
9.192012814 45.464643592,
9.191640825 45.464647090,
9.191622331 45.464506215,
9.190586853 45.464518970))')
);

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

Как это можно сделать с помощью MySQL? или кто-нибудь знает какие-либо ссылки, которые укажут мне в правильном направлении?

Ваш Ответ

4   ответа
1

Функция, приведенная вэта почта на форумах MySQL у меня отлично работает.

Это не очень быстро, и вы должны убедиться, что параметр "mp" тот же тип, что и используемый вами пространственный столбец (я использовал ogr2ogr для импорта шейп-файла Ordnance Survey в MySQL, поэтому пришлось изменить его с «MULTIPOLYGON» на «GEOMETRY»)

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededmapshaper.com/test/demo.htmlError: User Rate Limit Exceeded
0

Я переписалфункция это было дано в предыдущем посте @danherd, поэтому он может работать с реальными мультиполигонами, состоящими из более чем одного полигона. Для тех из вас, кто все еще продолжайте использовать старую версию MySql, это должно помочь.

Вот:

DELIMITER //

CREATE FUNCTION GISWithin(pt POINT, mp MULTIPOLYGON) RETURNS INT(1) DETERMINISTIC

BEGIN

DECLARE str_big, str, xy LONGTEXT;
DECLARE x, y, p1x, p1y, p2x, p2y, m, xinters DECIMAL(16, 13) DEFAULT 0;
DECLARE counter INT DEFAULT 0;
DECLARE p, pb, pe, sb, se, ct DECIMAL(16, 0) DEFAULT 0;

SELECT MBRWithin(pt, mp) INTO p;
IF p != 1 OR ISNULL(p) THEN
return p;
END IF;

SELECT X(pt), Y(pt), ASTEXT(mp) INTO x, y, str_big;
SET str_big = REPLACE(str_big, 'MULTIPOLYGON(((','');
SET str_big = REPLACE(str_big, ')))', '');
SET str_big = REPLACE(str_big, ')),((', '|');
SET str_big = CONCAT(str_big, '|');

SET sb = 1;
SET se = LOCATE('|', str_big);
SET str = SUBSTRING(str_big, sb, se - sb);

WHILE se > 0 DO
SET ct = ct + 1;
SET str = SUBSTRING(str_big, sb, se - sb);

SET pb = 1;
SET pe = LOCATE(',', str);
SET xy = SUBSTRING(str, pb, pe - pb);
SET p = INSTR(xy, ' ');
SET p1x = SUBSTRING(xy, 1, p - 1);
SET p1y = SUBSTRING(xy, p + 1);
SET str = CONCAT(str, xy, ',');

WHILE pe > 0 DO
SET xy = SUBSTRING(str, pb, pe - pb);
SET p = INSTR(xy, ' ');
SET p2x = SUBSTRING(xy, 1, p - 1);
SET p2y = SUBSTRING(xy, p + 1);
IF p1y < p2y THEN SET m = p1y; ELSE SET m = p2y; END IF;
IF y > m THEN
IF p1y > p2y THEN SET m = p1y; ELSE SET m = p2y; END IF;
IF y <= m THEN
IF p1x > p2x THEN SET m = p1x; ELSE SET m = p2x; END IF;
IF x <= m THEN
IF p1y != p2y THEN
SET xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x;
END IF;
IF p1x = p2x OR x <= xinters THEN
SET counter = counter + 1;
END IF;
END IF;
END IF;
END IF;
SET p1x = p2x;
SET p1y = p2y;
SET pb = pe + 1;
SET pe = LOCATE(',', str, pb);
END WHILE; 

SET sb = se + 1;
SET se = LOCATE('|', str_big, sb);

END WHILE;

RETURN counter % 2;

END

DELIMITER ; 
17

MySQL начиная с версии 5.1 поддерживает только операции наминимальные ограничивающие прямоугольники (MBR), Пока есть & quot;Содержит& Quot; функция, которая будет делать то, что вам нужно, она не полностью реализована и возвращается к использованиюMBRContains

Отсоответствующая страница руководства

Currently, MySQL does not implement these functions according to the specification. Those that are implemented return the same result as the corresponding MBR-based functions. This includes functions in the following list other than Distance() and Related().

These functions may be implemented in future releases with full support for spatial analysis, not just MBR-based support.

Что вы можете сделать, это позволить MySQL дать вам приблизительный результат, основанный на MBR, а затем опубликовать его, чтобы выполнить более точный тест. В качестве альтернативы, переключитесь наPostGIS!

(Update May 2012 - thanks Mike Toews)

MySQL 5.6.1+ предложенияфункции, которые используют формы объекта а не MBR

MySQL originally implemented these functions such that they used object bounding rectangles and returned the same result as the corresponding MBR-based functions. As of MySQL 5.6.1, corresponding versions are available that use precise object shapes. These versions are named with an ST_ prefix. For example, Contains() uses object bounding rectangles, whereas ST_Contains() uses object shapes.

Error: User Rate Limit Exceededthere is a whole suite of ST_ prefixed functions for v5.6Error: User Rate Limit Exceeded
6

Если вы не можете изменить dbs на тот, у которого пространственные операторы реализованы правильно, например, расширение PostGIS в PostgreSQLhttp://postgis.refractions.net/ Вы можете решить эту проблему, используя двухэтапный подход.

Сначала позвольте MySQL дать вам результат предварительной фильтрации ограничивающего прямоугольника, основанный на ограничивающем прямоугольнике (то, что он делает по умолчанию), используя оператор их пересечения (http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html#function_intersects). If queries are slow, make sure that you have an index on your geometry field first.

Затем скопируйте исходную геометрию, которую вы использовали в своем запросе, в геометрический объект из библиотеки геометрии ГИС, такой как GEOS (http://trac.osgeo.org/geos/) (На основе C ++, хотя он также имеет привязки для разных языков, таких как Python), Shapely (http://trac.gispython.org/lab/wiki/Shapely), OGR (или Java Topology Suite (JTS)http://www.vividsolutions.com/jts/jtshome.htm).

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

Лично я бы посмотрел примеры для OGR, поскольку у него есть большое сообщество, которое готово помочь.

О да, и извините за размещение таких ссылок ... Я думаю, так как я "новичок" Я могу опубликовать только одну ссылку (?)

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