Генерация случайных лат / длинных полигонов в стране? - PullRequest
1 голос
/ 21 мая 2019

Я должен генерировать случайные многоугольники с точками широты / долготы внутри другого многоугольника. (на самом деле, генерировать полигоны в пределах территории США) Кто-нибудь знает какой-либо API сопоставления, который может случайным образом генерировать многоугольник внутри многоугольника, например, границу страны? Или, возможно, как создать через код (C#)? спасибо

1 Ответ

0 голосов
/ 04 июня 2019

Мой первый вопрос: «Что такое случайный многоугольник?»Или, точнее, «Что такое случайный набор многоугольников?»Случайные точечные процессы довольно четко определены.Я сомневаюсь, что это относится к полигонам (хотя это действительно любопытно - поэтому для экспертов, пожалуйста, оставьте свои комментарии).

  • Вы хотите, чтобы они были случайными в том смысле, что их вершины являются случайными точками?- в каком случае вы получите что-то очень зазубренное, перекрывающееся и самопересекающееся?
  • Вы позволяете своим полигонам пересекаться в первую очередь?
  • Вы разрешаете своим полигонам иметь отверстия,и если да, является ли это свойство случайным само по себе?
  • Должны ли какие-либо другие свойства, такие как площадь, число вершин, окружность, следовать за распределениями вероятностей?

Ваше решение зависит от того, как вы ответитеэти вопросы.Я предложу тот, который относительно прост с использованием PostGIS (потому что это то, что я знаю).Следующий запрос создает полигоны Вороного из случайных точек, делает случайный выбор и объединяет результат, где это возможно.Им можно управлять с помощью двух параметров cells и density, которые определяют, на сколько разделов разделено пространство и какая доля этих разделов составляет ваш результат.

WITH params AS (
    SELECT
           (SELECT geom FROM natural_earth_countries WHERE admin = 'United States of America') AS geom,
           100000 AS cells,
           0.1 AS density
), voronois AS (
     SELECT (ST_Dump(ST_VoronoiPolygons(ST_GeneratePoints(p.geom, p.cells), extend_to := p.geom))).geom AS geom
     FROM params AS p
), voronois_select AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY Random()) % Round(1::NUMERIC/p.density) AS idx,
        ST_Intersection(v.geom, p.geom) AS geom
    FROM voronois AS v, params AS p
)
SELECT (ST_Dump(ST_Union(geom))).geom AS geom
FROM voronois_select
WHERE idx = 0

Примечание: ST_VoronoiPolygons не делаетне масштабируется хорошо.Вам придется увеличить ОЗУ для более высоких значений cells

Примечание: я помещаю params только в CTE, чтобы вы могли выполнять запрос в собственном (postgre) SQL без необходимости переносаэто в plpgsql (DO или CREATE FUNCTION).Это может быть немного медленнее в результате.

Примечание: добавьте к запросу префикс с CREATE TABLE random_polygons AS ..., и вы получите результат в таблице, готовой для добавления в качестве слоя, например, в QGIS.


Результаты:

USA with 100000 cells and density of 0.1 (10%) США с 100000 ячеек и плотностью 0,1 (10%)

USA with 100000 cells and density of 0.02 (2%) США с 100000 ячеек и плотностью 0,02 (2%)

USA with 1000 cells and density of 0.1 (10%) США с 1000 ячеек и плотностью 0,1 (10%)


Опять же, только один из множества способов сделать это.Но если вы хотите иметь больший контроль над формой многоугольников, используя вышеупомянутое решение, вы можете либо сделать это, манипулируя процессом базовой точки, то есть написав свой собственный ST_GeneratePoints, чтобы точки были более кластеризованными.Или вы создаете вложенные диаграммы Вороного, причем вторая имеет гораздо большую плотность, чем первая.

Обе модификации дадут более компактные, но сложные "случайные" полигоны.

...