Страница 1 из 1

Создаётся мультигеометрия, когда её быть не должно.

Добавлено: 16 сен 2012, 19:41
SS_Rebelious
В случае, если линия пересекает невыпуклый полигон и пр этом касается одной из его вершин, то при использовании функции intersection() (пересекаем линию полигоном) получается мультигеометрия (вместо простой), части которой имеют общую точку. Такое поведение крайне неприятно в задачах, чувствительных к типу геометрии.

Пример:

Код: Выделить всё

>>> poly = QgsGeometry.fromPolygon([  [ QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,1), QgsPoint(3,1), QgsPoint(3,2),  QgsPoint(2,2), QgsPoint(2,1), QgsPoint(1,1), QgsPoint(1,3)   ] ])
>>> line = QgsGeometry.fromPolyline( [ QgsPoint(0,0), QgsPoint(4,4) ] )
>>> li = line.intersection(poly)
>>> li.exportToWkt()
PyQt4.QtCore.QString(u'MULTILINESTRING((1.000000 1.000000, 2.000000 2.000000), (2.000000 2.000000, 3.000000 3.000000))')
Отсечённый участок полностью лежит внутри полигона, а потому должен быть простой линией.

Re: Создаётся мультигеометрия, когда её быть не должно.

Добавлено: 17 сен 2012, 11:23
Voltron
SFS ещё не смотрел, но что-то мне подсказывает, что поведение правильное

Re: Создаётся мультигеометрия, когда её быть не должно.

Добавлено: 17 сен 2012, 17:19
SS_Rebelious
Думаю, это просто недоработка, когда проглядели частный случай. С точки зрения частной реализации алгоритма отсечения такое поведение может быть закономерным не представляющим особых проблем во многих случаях (но не во всех), однако (и это самое главное), такое поведение противоречит логике. Линия, касающаяся края многоугольника, и линия пересекающая границу полигона - разные вещи. В приведённом примере линия именно касается границы многоугольника, а не пересекает. Если быть последовательным в логике реализации алгоритма отсечения, то геометрия, получаемая при пересечении линии и полигона, в случае, когда часть линии лежит на ребре полигона, должна представлять собой совокупность бесконечного множества отдельных точек, ибо раз линия касается ребра в каждой точке, то и каждая точка должна составлять отдельный узел. Однако, на практике подобное отсечение работает относительно адекватно - линия обрезается не в каждом месте касания, а только в местах пересечения линией границы полигона (ну и плюс, в местах, где на этом ребре оказался лишний узел).

Почему важно соблюдение логики создания геометрий (безотносительно QGIS)? - При пересечении линией (linestring) выпуклого полигона не может быть больше 2-точек пересечения. Если их больше (и мы имеем мультигеометрию на выходе), то это означает, что полигон - невыпуклый. При пересечении линией невыпуклого многоугольника (следуя логике) мы получаем мультигеометрию в случае, если линия "входит" в полигон более одного раза или касается как минимум двух его вершин, или пересекает полигон и касается грани или вершины полигона на некотором расстоянии от пересечения (ну и комбинации указанных случаев). Если эта логика не соблюдается (как в нашем случае), то это ведёт к осложнениям в проектировании приложений.

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