Usted está tratando de construir un polígono con una larga lista de coordenadas, eso no servirá. La lista de puntos es como se define una polilínea, sin embargo QgsGeometry::fromPolygon() espera un polígono.
Además, usted quiere crear muchos polígonos, pero le está dando una sola lista secuencial de todas las coordenadas, por lo que está creando un polígono que pasa por cada coordenada.
Los polígonos se definen como una cadena de líneas de bucle cerrado. Los polígonos con anillos en su interior (como un donut) se definen con una cadena de líneas de bucle cerrado para su anillo exterior (el límite exterior) y otra para su anillo interior (el límite interior). Esto se hace en PyQGIS con una lista de listas, donde cada lista interior es una lista de coordenadas de bucle cerrado. Como tal:
from qgis.core import QgsGeometry, QgsPoint
# Define exterior ring coordinates, notice how the first point repeats at the end of the list.
p1 = QgsPoint(0, 0)
p2 = QgsPoint(10, 0)
p3 = QgsPoint(10, 10)
p4 = QgsPoint(0, 10)
li_out_ring = [p1, p2, p3, p4, p1]
# Define interior ring coordinates, notice how the first point repeats at the end of the list.
p5 = QgsPoint(2, 2)
p6 = QgsPoint(8, 2)
p7 = QgsPoint(8, 8)
p8 = QgsPoint(2, 8)
li_inn_ring = [p5, p6, p7, p8, p5]
# Creates geometry.
polygon = QgsGeometry.fromPolygon([li_ext_ring, li_inn_ring])
Este es el resultado:
![Polygon with ring]()
Tendrás que repetirlo para cada polígono que quieras crear y que comprenda tu forma final.
ACTUALIZACIÓN : ¿Qué hacer cuando se tiene una lista de coordenadas sin distinción de anillos interiores y exteriores?
Si su polígono sólo tiene un anillo interior y su anillo exterior tiene un forma convexa (que es el caso de un donut), puedes encontrarlo y separar las geometrías. La forma de hacerlo es que primero reúnes todos los puntos en una geometría Multipunto. Luego encuentras el anillo exterior creando un Casco convexo . Por último, se comparan los puntos que están en la geometría del casco convexo con el conjunto completo de puntos, y los que queden fuera formarán parte del anillo interior.
def create_wkt_from_list(li_points):
# li_points must be a python list() of QgsPoint objects.
wkt = 'MULTIPOINT('
for point in li_points:
x = point.x()
y = point.y()
wkt += '({} {}), '.format(x, y)
wkt = wkt[:-1] + ')'
return wkt
wkt = create_wkt_from_list(li_points)
multipoint = QgsGeometry.fromWkt(wkt)
out_ring = multipoint.convexHull()
A partir de aquí puedes construir un iterador que recorra cada vértice de tu anillo_de_salida y lo compare con tu lista inicial, o algo parecido. Probablemente hay una forma más eficiente de hacerlo, pero esto es lo esencial.
¿Qué pasa si mi polígono no es convexo? Existen métodos para encontrar el casco cóncavo pero no son deterministas, por lo que no sirven para diferenciar los anillos exteriores de los interiores.
¿Qué pasa si mi polígono tiene muchos anillos interiores? El método anterior seguirá funcionando, pero no habrá forma de diferenciar los anillos, por lo que acabará con un solo anillo interior, probablemente de forma extraña.
1 votos
¿Es posible hacer como un gran círculo y eliminar de este círculo (con el diferencia la herramienta) el pequeño?
0 votos
No puedo clasificar los puntos que constituyen el límite interior o el límite exterior de la característica. Así que eso descarta la diferencia de círculo interior y exterior. También necesito tener un script de python para hacer eso.