назначать и перемещать центроиды на их полигоны

9

Я использую QGIS 1.8 Lisboa. После вычисления центроидов из шейп-файла многоугольника, если некоторые из них лежат вне контуров многоугольника, я бы хотел переместить их на многоугольник, с которого они пришли. Критерий должен быть однозначным, поскольку я должен использовать их для извлечения координат, которые будут использоваться в качестве идентификационного кода самого многоугольника. Следовательно, процедура должна выводить одно и то же местоположение точки каждый раз, когда она выполняется для одного и того же многоугольника (а не случайное положение, подобное тому, которое задано функцией «случайные точки», которая дает новый результат при каждом запуске).

umbe1987
источник
1
Звучит как два вопроса. Если я правильно понимаю, вы хотите (а) добавить случайные точки внутри многоугольника и (б) дать им или многоугольнику уникальный идентификатор, основанный на этом. Самое простое, что приходит на ум для (a), - это использовать существующие возможности случайных точек в QGIS, а затем просто пересечь это облако точек с вашим полигоном.
lynxlynxlynx
использование функции «случайные точки» в разное время с одними и теми же полигонами приводит к разным результатам (а именно, положение точек, полученных из каждого полигона, отличается при каждом новом использовании функции), и я хочу создать метод, который бы дал мне всегда одна и та же точка на полигон, откуда я мог бы извлечь координаты, которые я хочу использовать в качестве идентификационного кода для самих полигонов.
umbe1987
используйте инструмент fTools 'true centroid' под инструментами геометрии - docs.qgis.org/html/en/docs/user_manual/plugins/…
Mapperz
это только дает мне центроид, но это также может находиться вне полигона, которого я должен избегать. Мне нужно переместить их на полигон, из которого они получены, используя функцию, например, минимальное расстояние (но мне не интересно расстояние, я хочу, чтобы оно было перемещено). В другом блоге кто-то сказал мне использовать ST_PointOnSurface из PostGIS (но я использую QGIS).
Umbe1987
2
это дубликат gis.stackexchange.com/questions/50029/… сейчас?
Подземье

Ответы:

7

Вы можете использовать библиотеку питона Shapely, которая предоставляет функцию, representative_point()которая гарантированно находится внутри многоугольника.

Вот скрипт Python, который можно запустить в консоли QGIS Python. Слой полигона, для которого вы хотите создать атрибут, должен быть выбран. Функция берет имя атрибута, который вы хотите обновить. Атрибут должен уже существовать в вашем слое, он должен иметь строковый тип и быть достаточно длинным (30 символов).

Вот пример точек, найденных алгоритмом:

import shapely.wkb

def setIDPoint(attributename):
 layer = qgis.utils.iface.activeLayer()
 provider = layer.dataProvider()
 fields = provider.fields()
 provider.select(provider.attributeIndexes() )
 attributeID = provider.fieldNameIndex(attributename)
 feature = QgsFeature()
 layer.startEditing()
 while provider.nextFeature(feature):
  wkb = feature.geometry().asWkb()
  polygon = shapely.wkb.loads(wkb)
  reprPoint = ','.join([str(polygon.representative_point().x), str(polygon.representative_point().y)] )
  feature.changeAttribute(attributeID, reprPoint)
  layer.updateFeature(feature)
 layer.commitChanges()
Джейк
источник
Я пытаюсь проверить это, кажется, именно то, что я искал. Я дам Тебе знать, как только я его запущу!
Umbe1987
Одна вещь, которую я не понял, это то, что вы подразумеваете под «это должен быть строковый тип, и он должен быть достаточно длинным (30 символов)». Эта библиотека работает напрямую с полигональными shpfiles? Если это так, я должен создать новое поле строкового типа на вкладке Att минимум с 30 символами, и это будет то, что будет обновлено?
umbe1987
@ user9518: Да, способ написания функции в тот момент, когда вам нужно создать атрибут в таблице самостоятельно, а затем только передать имя поля функции. Сценарий также может быть легко адаптирован для создания самого необходимого поля, если это то, что нужно.
Джейк
Я просто скучаю по одной вещи. Кажется, теперь я определяю функцию (или класс), набирая «def», но потом, когда я заканчиваю писать скрипт, ничего не происходит. Как я могу наконец получить результат в моей таблице?
Umbe1987
1
Работало отлично !!! Я предполагаю, что координаты написаны в соответствии с системой координат слоя, и что если я хочу иметь точки, мне нужно создать shp с этими координатами, верно? Если бы вы были здесь, я бы предложил вам как минимум 3 пива! Большое спасибо за ваши усилия !!!
Umbe1987
5

Инструмент центроида ftools может поместить центроид вне многоугольника, если он вогнутый.

ST_PointOnSurfaceобязательно сделаем то, что вы хотите. Вы можете использовать команду из QGIS, если вы установили ее с помощью SPIT, чтобы загрузить свой шейп-файл в PostGIS, а затем использовать плагин PgQuery для запуска запроса.

В качестве альтернативы, если установка PostGIS слишком сложна для одноразового использования, вы можете использовать Spatialite из QGIS. Затем вы можете использовать плагин QSpatiaLite, чтобы импортировать ваши данные в SpatiaLite и выполнить запрос (SpatialLite honours ST_PointOnSurface).

MappaGnosis
источник
2

когда я вас правильно понял, используйте: Vector-> Research Tools_> Random Points. Теперь выберите в разделе «Проект стратифицированной выборки (отдельные полигоны)» значение из поля ввода и используйте соответствующее поле, которое дает числовое значение точек, которые должны быть сгенерированы для каждого отдельного полигона.

Kurt
источник
что ты имеешь в виду под "подходящим полем"? Я думал использовать центроид, а затем связать его с ближайшей частью многоугольника, на который он ссылается, если он лежит вне контура, например, путем вычисления минимального расстояния этой точки до ближайшего многоугольника. Цель состоит в том, чтобы затем извлечь координаты этой точки, чтобы использовать их в качестве уникального специального идентификационного кода многоугольника.
umbe1987
По сути, я пытаюсь назначить каждый центроид своему относительному многоугольнику и переместить его так, чтобы он лежал внутри своего многоугольника (или, по крайней мере, касался его границы).
umbe1987
@ user9518: извините, я неправильно понял ваш вопрос. Я думал, что вам нужно определенное количество случайных точек в каждом поли, например, 2 точки на поли 1, 10 точек на поли 2 и т. Д. Поэтому термин «соответствующее поле». конечно, вы можете выбрать 1 для «использовать это количество точек», чтобы генерировать только одну точку для каждого поли. эта точка находится внутри поли или, по крайней мере, касается ее границы. но эта точка все еще встречается случайно, поэтому, когда вы повторяете процедуру, вы получаете другие очки :-(
Курт
1

Плагин realcentroids, доступный для установки через Plugins> Manage and Install Plugins, работал для меня в QGIS 2.2 для создания центроидоподобных точек, принудительно создаваемых внутри каждого многоугольника, если он вогнутый (точка будет лежать очень близко к краю). Я попробовал инструмент «Случайные точки», как предложил Курт, и хотя я указал 1 точку на многоугольник, он генерирует два вместо. Дополнительным недостатком является то, что в большинстве случаев точки не представляют центроид, поскольку они являются случайными.

http://www.agt.bme.hu/gis/qgis/realcentroid/

Александра Матес
источник