40 votos

Generación de puntos dentro de un polígono con QGIS

Estoy utilizando QGIS.

Tengo una característica poligonal y quiero poder generar puntos dentro de ella. Necesito esto para una tarea de clasificación.

Generar puntos aleatorios hasta que uno esté dentro del polígono no funcionaría porque es realmente impredecible el tiempo que tarda.

4 votos

Por el contrario, el tiempo es previsible. Es proporcional a la relación entre el área de extensión del polígono dividida por el área del polígono, multiplicada por el tiempo necesario para generar y probar un solo punto. El tiempo varía un poco, pero la variación es proporcional a la raíz cuadrada del número de puntos. Para números grandes, esto es irrelevante. Si es necesario, divida los polígonos tortuosos en trozos más compactos para reducir la proporción de área a un valor bajo. Sólo los polígonos fractales le darán problemas, ¡pero dudo que usted los tenga!

3 votos

1 votos

23voto

Slayd Puntos 111

Comience por descomponer el polígono en triángulos y, a continuación generar puntos dentro de esos . (Para una distribución uniforme, ponderar cada triángulo por su área).

3 votos

+1 Simple y eficaz. Vale la pena señalar que se pueden generar puntos aleatorios uniformes dentro de un triángulo sin ningún rechazo, porque existen mapeados (fáciles de calcular) que preservan el área entre cualquier triángulo y un triángulo rectángulo isósceles, que es la mitad de un cuadrado, es decir, la mitad en la que la coordenada y supera a la coordenada x. Genera dos coordenadas aleatorias y ordénalas para obtener un punto aleatorio en el triángulo isósceles, luego vuelve a mapearlo en el triángulo original.

0 votos

+1 Me gusta mucho el debate sobre coordenadas trilineales al que hace referencia el artículo que cita. Supongo que esto se podría aplicar a una esfera cuya superficie se represente como una teselación de triángulos. En un plano proyectado, no sería una distribución verdaderamente aleatoria, ¿verdad?

0 votos

@whuber -- +1 de nuevo a usted. Otra forma (en el enlace, pero se agitó la mano por encima de ella) es reflejar los puntos rechazados desde el cuadrilátero de muestreo uniforme a través del borde compartido y de nuevo en el triángulo.

17voto

tobes Puntos 19

La herramienta Puntos aleatorios puede utilizarse con una capa límite.

enter image description here

Si está buscando código, el código fuente del plugin subyacente debería serle de ayuda.

1 votos

Incluso 5 años después, sigue siendo muy útil.

14voto

Seven Puntos 111

Hay algunas buenas bibliotecas que hacen la mayor parte del trabajo pesado por ti.

Ejemplo de uso de [shapely][1] en python.

import random
from shapely.geometry import Polygon, Point

def get_random_point_in_polygon(poly):
     minx, miny, maxx, maxy = poly.bounds
     while True:
         p = Point(random.uniform(minx, maxx), random.uniform(miny, maxy))
         if poly.contains(p):
             return p

p = Polygon([(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)])
point_in_poly = get_random_point_in_polygon(mypoly)

O utilice .representative_point() para obtener un punto dentro del objeto (como menciona dain):

Devuelve un punto calculado a bajo coste que se garantiza que está dentro del objeto geométrico.

poly.representative_point().wkt
'POINT (-1.5000000000000000 0.0000000000000000)'

  [1]: https://shapely.readthedocs.io

2 votos

¿No debería ser de shapely.geometry import...?

1 votos

También puede utilizar la función representative_point método: shapely.readthedocs.io/es/latest/

10voto

Ross Puntos 19037

Podría determinar la extensión del polígono y luego restringir la generación de números aleatorios para los valores X e Y dentro de esas extensiones.

Proceso básico: 1) Determinar maxx, maxy, minx, miny de los vértices del polígono, 2) Generar puntos aleatorios utilizando estos valores como límites 3) Comprobar la intersección de cada punto con el polígono, 4) Deje de generar cuando usted tiene suficientes puntos que satisfagan la prueba de intersección

He aquí un algoritmo (C#) para la prueba de intersección:

bool PointIsInGeometry(PointCollection points, MapPoint point)
{
int i;
int j = points.Count - 1;
bool output = false;

for (i = 0; i < points.Count; i++)
{
    if (points[i].X < point.X && points[j].X >= point.X || points[j].X < point.X && points[i].X >= point.X)
    {
        if (points[i].Y + (point.X - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < point.Y)
        {
            output = !output;
        }
    }
    j = i;
}
return output;
}

6voto

sgwill Puntos 2444

Si R es una opción, véase ?spsample en el sp paquete. Los polígonos se pueden leer desde cualquier formato compatible con GDAL incorporado en el paquete rgdal, y luego spsample trabaja directamente sobre el objeto importado con diversas opciones de muestreo.

0 votos

+1 - Dado que R es de código abierto si uno quiere replicar siempre se puede ir a la fuente para ver cómo se hacen. Para los patrones puntuales uno también puede estar interesado en las herramientas de simulación en el paquete spatstat.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X