Как использовать ST_Intersection?

15

Вот краткое изложение того, что я пытаюсь сделать: у меня есть 3 таблицы в Postgres, 'a' и 'b', у каждой есть столбец Polygon, а у 'c' есть столбец Point. Здесь я пытаюсь получить пересечения геометрий между «a», «b» и «c» и отобразить такие геометрии на векторном слое OpenLayers.

Я уже знаю, как отображать любую геометрию из строки в OpenLayers, но у меня проблемы с функцией PostGIS ST_Intersection, я делаю это:

SELECT ST_Intersection(a.geom, b.geom) as inter from a, b;

где a.geom и b.geom оба являются столбцами геометрии, и я получаю это сообщение об ошибке:

NOTICE:  TopologyException: found non-noded intersection between 515172 2.14408e+06, 497067 2.13373e+06 and 501321 2.13546e+06, 471202 2.14843e+06 500621 2.13576e+06 
ERROR:  GEOS Intersection() threw an error!

Также я попытался выразить результирующую геометрию как текст с помощью ST_AsText следующим образом:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as inter from a, b;

но он отправляет мне это сообщение об ошибке:

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Я не знаю, что я делаю неправильно, я просто хочу, чтобы WKT Polygons отображал его на OpenLayers, вот как я отображаю геометрию из WKT:

                    var in_options = {
                        'internalProjection': new OpenLayers.Projection("EPSG:4326"),
                        'externalProjection': new OpenLayers.Projection("EPSG:4326")
                    }; 

                    var fea= new OpenLayers.Format.WKT(in_options).read(data); //data is the string with the WKT
                    vectorLayer.addFeatures([fea]); //this piece of code works great
                    map.zoomToExtent(bounds);

ОБНОВЛЕНИЕ: я попробовал следующее:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab FROM a INNER JOIN b ON 
ST_Intersection(a,b) WHERE ST_Overlaps(a.geom, b.geom) 
AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

но я получаю следующее сообщение об ошибке:

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Я добавил isvalid, чтобы убедиться, что оцениваются только действительные полигоны, но он говорит, что ошибка в ST_Intersection (a, b), a, b и c имеют одинаковый SRID, так что я действительно запутался, извините, если я спрашиваю слишком много, но я новичок в PostGIS, так что я надеюсь, что я вас не побеспокою. Благодарю.

Уриэль
источник
1
Что SELECT PostGIS_Full_Version();возвращает?
Майк Т
POSTGIS = "1.4.0" GEOS = "3.1.0-CAPI-1.5.0" PROJ = "Rel. 4.7.1, 23 сентября 2009 г." USE_STATS
Уриэль

Ответы:

8

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

Подземье
источник
Я попробовал это: ВЫБЕРИТЕ ST_Intersection (a.geom, b.geom) как intersect_ab ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ b НА ST_Intersection (a, b) ГДЕ ST_Overlaps (a.geom, b.geom) И ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; но он вернул ту же ошибку: ** ОШИБКА: функция st_intersection (a, b) не существует. СОВЕТ: ни одна функция не соответствует заданному имени и типу аргумента. Возможно, вам придется добавить явные приведения типов. ** Я действительно застрял в этом, если вы можете мне помочь, я очень ценю это.
Уриэль
Попробуйте суммарное (a.geom) и суммарное (b.geom), чтобы изучить значения.
Подземье
резюме -------------------------- Многоугольник [BS] с 1 кольцом кольца 0 имеет 4 очка Многоугольник [BS] с 1 кольцом кольца 0 имеет 5 очков Полигон [BS] с 1 кольцом кольца 0 имеет 10 очков
Уриэль
Да, это должно быть ST_Intersection (a.geom, b.geom), а не ST_Intersection (a, b)
Подземье
6

Ключ

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Как говорится в сообщении об ошибке, вы не можете использовать st_intersection таким образом. Обобщая другие ответы, вы должны использовать что-то вроде этого:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab 
FROM a INNER JOIN b ON ST_Intersects(a.geom,b.geom)
WHERE ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

AFAIK Нет смысла использовать st_overlaps и st_intersects в одном предложении, поскольку они очень похожи .

Франциско Пуга
источник
4

Я проверил между разными слоями полигонов, и это не удалось, если в одном из слоев есть хотя бы неправильная геометрия. Вы проверяли правильность своих полигонов, используя ST_isvalid (the_geom)? Это может быть ключом.

Фабьен Анселин
источник
Я попробовал это: ВЫБЕРИТЕ ST_Intersection (a.geom, b.geom) как intersect_ab ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ b НА ST_Intersection (a, b) ГДЕ ST_Overlaps (a.geom, b.geom) И ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; но он вернул ту же ошибку: ** ОШИБКА: функция st_intersection (a, b) не существует. СОВЕТ: ни одна функция не соответствует заданному имени и типу аргумента. Возможно, вам придется добавить явные приведения типов. ** Я действительно потерялся относительно того, почему это не работает
Уриэль
2

Попробуйте что-то вроде этого:

SELECT  ST_Intersection(a.geom, b.geom) As intersect_ab
    FROM a INNER JOIN b ON ST_Intersection(a,b)
    WHERE ST_Overlaps(a.geom, b.geom)
    ;

Источник

CaptDragon
источник
Я тоже пытался, но он возвращает то же сообщение об ошибке: СОВЕТ: ни одна функция не соответствует заданному имени и типу аргумента. Возможно, вам придется добавить явные приведения типов.
Уриэль
Как насчет того, чтобы использовать «INNER JOIN b ON ST_Intersection (a.geom, b.geom)»?
CaptDragon
Он говорит: ОШИБКА: аргумент JOIN / ON должен иметь тип логический, а не тип геометрии.
Уриэль
shizer ... должно быть что-то не так с данными или что-то, потому что этот тип запроса работает для меня.
CaptDragon
Я добавил AND ST_isvalid (a.geom) = 't' И ST_isvalid (b.geom) = 't'; в конце, чтобы оценить только действительные геометрии, но это говорит мне об ошибке в том st_intersection (a, b)
Уриэль
1

Я пытался исключить неверные геометрии, но это не сработало, поэтому в конце концов мне пришлось удалить все неверные геометрии, а затем использовать это:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as intersect_ab FROM a,b 
WHERE ST_Overlaps(a.geom, b.geom) AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

Как вы можете видеть, я пропустил часть ST_Intersection (a, b), и это сработало замечательно, я, к сожалению, из-за того, что не смог найти способ исключить любую некорректную геометрию из моего выбора, в любом случае спасибо всем за помощь прочь.

Уриэль
источник
0

У меня была эта проблема однажды.

<pre>NOTICE:  TopologyException: found non-noded intersection between xxx, xxxx and xxx, xxx  ERROR:  GEOS Intersection() threw an error!</pre>

Мне удалось устранить эту ошибку, используя этот метод.
- Использовать QGIS
- Добавить векторный слой из вашей базы данных
- Возьмите точку из сообщения об ошибке и найдите его в QGIS.
   «QuickWKT» (плагин) можно использовать, чтобы найти ее.
- Затем вы увидите проблемную строку
- Включите режим редактирования.
- Выберите «инструмент узла», чтобы показать зеленый узел (проблема с узлом)
- отодвиньте узел от узла перекрытия
- сохраните изменения

Ruthe
источник