powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
8 сообщений из 8, страница 1 из 1
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977108
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
Posgresql 9.6
PostGis 2.4.2

При выполнении операции пересечения
Код: plsql
1.
2.
3.
4.
select g.key,g.value
from geotable g
where g.value>100
and st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true;


появляется ошибка
Код: plsql
1.
XX000: GEOSIntersects: TopologyException: side location conflict at 2480456.5554545452 264161.31727272732


Дело, конечно в ошибках в геометрии. Без проблем мы находим 1000 битых записей(всего в таблице 100000 записей) запросом
Код: plsql
1.
select key,ST_IsValidReason(geom) from geotable where st_isvalid(geom)!=true;



Но битые геометрии в выборку не попадают(у всех битых записей value<100). Значит такое возникает при проходе по пространственному индексу, который построен по всей таблице.
Код: plsql
1.
CREATE INDEX sx_idx ON geotable USING gist (geom);



Изменим индекс
Код: plsql
1.
CREATE INDEX sx_idx ON geotable USING gist (geom) where st_isvalid(geom)=true;


и ошибка уйдет.

Но меня интересует как всё-таки можно найти на какой именно записи спотыкалось выполнение без изменения индекса?
Код: plsql
1.
XX000: GEOSIntersects: TopologyException: side location conflict at 2480456.5554545452 264161.31727272732



искал по этим значениям в координатах битых объектов, и в результате ST_IsValidReason, но такие записи не находятся
Код: plsql
1.
2.
select key,ST_IsValidReason(geom) from geotable where st_isvalid(geom)!=true and st_astext(geom) like '%264161.31727272732%';
select key,ST_IsValidReason(geom) from geotable where st_isvalid(geom)!=true and ST_IsValidReason(geom) like '%264161.31727272732%';



К сожалению, исправить всё через st_makevalid недопустимо, возможно несколько записей только и то с большим и долгим согласованием.
Интересно было бы найти запись, которая не является частью выборки, но входит в индекс и мешает выполнению.
Возможно кто-то сталкивался с решением подобной задачи-буду очень благодарен. Спасибо.
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977133
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermoz

К сожалению, исправить всё через st_makevalid недопустимо, возможно несколько записей только и то с большим и долгим согласованием.
Интересно было бы найти запись, которая не является частью выборки, но входит в индекс и мешает выполнению.
Возможно кто-то сталкивался с решением подобной задачи-буду очень благодарен. Спасибо.


если там есть primary key - то просто по нему перебираете построчно все записи через запрос вида

Код: plsql
1.
2.
3.
4.
5.
select g.key,g.value
from geotable g
where g.value>100
and st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true
and PRIMARY_KEY_col=...;



и смотрите на каких id оно ломается.
Скрипт на psql (через /gexec) или на bash пишется в пару строчек.
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977184
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermoz,

кстати далеко не факт что "Но битые геометрии в выборку не попадают(у всех битых записей value<100)" - чем то вам поможет...
а попробуйте запрос написать как

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select g.key,g.value
from
(
from geotable g
where g.value>100
offset 0) as g
where
st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true;


не ушла ли ошибка?

ps: база совершенно не обязана проверять сначала g.value а потом лезть в st_intersects
она вполне может и наоборот сделать.
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977188
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,большое спасибо за советы. Попробую перебором ключей найти. и вариант с offset тоже проверю
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977695
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,действительно с offset 0 запрос сработал - индекс в плане не участвовал. Еще раз спасибо за совет- возьму такой способ на вооружение.

проверил вариант со скриптом и перебором.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
do
$$
declare
	tKey bigint;
	rec record;
begin
	for rec in(select g.key,g.value from geotable g where g.value>100)
	loop
		raise info '%',rec.key;
		begin
			select g.key into tKey
				from geotable g
					where g.value>100
						and g.key=rec.key
						and st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true;
		exception when others then 
			raise notice '%',tKey;
		end;
	end loop;
end$$;



но результата не выдалось, т.к. условие g.value>100 фильтрует данные так, что запрос
Код: plsql
1.
select g.key,g.value from geotable g where g.value>100


ничего не возвращает, и не выполняется ни одной итерации цикла.



Но всё-таки интересно еще найти запись, которая в индексе сидит. Интересно, это вообще возможно без выполнения под отладкой? можно ли "заглянуть в индекс" и посмотреть как идет пробег по дереву?
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977705
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermoz
Maxim Boguk,действительно с offset 0 запрос сработал - индекс в плане не участвовал. Еще раз спасибо за совет- возьму такой способ на вооружение.

проверил вариант со скриптом и перебором.
...
ничего не возвращает, и не выполняется ни одной итерации цикла.

Но всё-таки интересно еще найти запись, которая в индексе сидит. Интересно, это вообще возможно без выполнения под отладкой? можно ли "заглянуть в индекс" и посмотреть как идет пробег по дереву?


Тоже самое сделайте но без g.value>100 условия и все увидите.
Я вам уже написал что база сначала пробует условия st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true
а потом уже проверят value>100
и попадает на невалидные строки таким образом.

'Но битые геометрии в выборку не попадают(у всех битых записей value<100).' - вот если сделать с offset 0 - тогда действительно не попадают.
А вот в просто запросе еще как попадают.
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977707
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk, "Тоже самое сделайте но без g.value>100 условия и все увидите." но тогда ведь это будет равнозначно запросу с st_isvalid!=true, т.к. большинство невалидной геометрией выдаст подобную ошибку.
Код: plsql
1.
select key,ST_IsValidReason(geom) from geotable where st_isvalid(geom)!=true;


Запрос обязательно упадет на объектах с невалидной геометрией- эти объекты я получил запросом выше. Но, вероятно, не все 1000 битых объектов мешают выполнению запроса для точки POINT(1 1), а только несколько. и вот эти интересно найти.

Как вариант, возможно, ловить исключение на варианте "Тоже самое сделайте но без g.value>100 условия и все увидите.", и сравнивать его текст с изначальной ошибкой
Код: plsql
1.
XX000: GEOSIntersects: TopologyException: side location conflict at 2480456.5554545452 264161.31727272732
...
Рейтинг: 0 / 0
Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
    #39977738
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получилось найти таким способом, как советовал Maxim Boguk + сравнение по координатам ошибки.
Возможно, кому-нибудь тоже пригодится

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
do
$$
declare
	tKey bigint;
	rec record;
	error_text text;
	error_info text:='GEOSIntersects: TopologyException: side location conflict at 10398.659 3844.9200000000001';	
begin
	for rec in(select g.key,g.value from geotable g)
	loop
		begin
			select g.key into tKey
				from geotable g
					where g.key=rec.key
						and st_intersects(g.geom,st_geomfromtext('POINT(1 1)'))=true;
		exception when others then 
			GET STACKED DIAGNOSTICS error_text = MESSAGE_TEXT;
			if error_text=error_info then
				raise info '%',rec.key;	
			end if;			
		end;
	end loop;
end$$;
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Postgis: GEOSIntersects: TopologyException: side location conflict. Как найти строку?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]