1

I have to generate random polygons with lat/lon points within another polygon (actually, generate polygons within USA area) Does anybody know of any mapping API that can randomly generate a polygon within a polygon, such as a country boundary? Or perhaps how to create through the code (C#)? thanks

Minhaj Patel
  • 579
  • 1
  • 6
  • 21
  • see https://gis.stackexchange.com/questions/207731/how-to-generate-random-coordinates-in-a-multipolygon-in-python or https://stackoverflow.com/questions/9104908/random-geographic-coordinates-on-land-avoid-ocean – Ian Turton May 22 '19 at 07:14
  • Possible duplicate of [Random geographic coordinates (on land, avoid ocean)](https://stackoverflow.com/questions/9104908/random-geographic-coordinates-on-land-avoid-ocean) – Ian Turton May 22 '19 at 07:15

1 Answers1

-1

My first question would be: "What is a random polygon?" Or more precisely "What is a random polygon set?" Random point processes are pretty well-defined. I doubt this is the case for polygons (really curious though - so for the experts, please leave your comments).

  • Do you want them to be random in the sense that their vertices are random points? - in which case you would get something very jagged and overlapping and self-intersecting?
  • Do you allow your polygons to intersect in the first place?
  • Do you allow your polygons to have holes, and if so is this property random in itself?
  • Should any other properties, such as area, number of vertices, circumference follow probability distributions?

Your solution depends on how you answer these questions. I will offer one that is relatively simple using PostGIS (because that's what I know). The following query creates Voronoi polygons from random points, makes a random selection and merges the result where possible. It can be controlled using two parameters cells and density, which specify in how many partitions the space is divided and what share of these partitions constitute your result.

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

Note: ST_VoronoiPolygons doesn't scale well. You will have to increase RAM for higher values of cells

Note: I'm only putting params in a CTE so you can run the query in native (postgre)SQL, without the need to wrap it in plpgsql (DO or CREATE FUNCTION). It might be a bit slower as a result.

Note: prefix the query with CREATE TABLE random_polygons AS ... and you got the result in a table ready to add as a layer in e.g. QGIS.


Results:

USA with 100000 cells and density of 0.1 (10%) USA with 100000 cells and density of 0.1 (10%)

USA with 100000 cells and density of 0.02 (2%) USA with 100000 cells and density of 0.02 (2%)

USA with 1000 cells and density of 0.1 (10%) USA with 1000 cells and density of 0.1 (10%)


Again, just one out of a myriad of ways of doing this. But if you want to have more control about the shape of the polygons using the above solution, you could either do this by manipulating the underlying point process, i.e. writing your own ST_GeneratePoints, so that points are more clustered. Or you create nested Voronoi diagrams, with the second one having a much higher density than the first one.

Both modifications would yield more compact yet complex "random" polygons.

chris
  • 423
  • 2
  • 9