13 votos

¿Cómo modificar un polígono para que sea más rectangular?

existing buildings

Tengo algunos edificios que fueron rápidamente digitalizados a partir de una imagen aérea. Como puedes ver, la mayoría de los polígonos no son rectangulares. ¿Cómo puedo modificar los polígonos para hacerlos más rectangulares? ¿Hay alguna ecuación que pueda resolver un rectángulo a partir de un grupo de puntos? No quiero volver a digitalizar los polígonos. Se supone que los polígonos representan edificios. Estoy usando Qgis.

Intenté el código de @Matte pero resultó en enter image description here

8voto

Yada Puntos 9489

El siguiente código usa la geometría analítica para cambiar cada polígono cuasi rectangular en rectangular y podría ser usado:

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

n = len(feats)

crs = layer.crs()
epsg = crs.postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'rectangle',
                           'memory')

prov = mem_layer.dataProvider()

for feature in feats:

    geom = feature.geometry()

    xmin, ymin, xmax, ymax = geom.boundingBox().toRectF().getCoords()

    points = feature.geometry().asPolygon()[0]

    for i in range(len(points)-1):
        if points[i][1] == ymax and points[i+1][1] < points[i][1]:
            idx = i
        if points[i][1] == ymax and points[i-1][1] < points[i][1]:
            idx = i-1

    rectangle = []

    #x,y coordinates of first point
    x1 = points[idx][0] 
    y1 = points[idx][1]

    rectangle.append(QgsPoint(x1,y1))

    #x,y coordinates of second point
    x2 = points[idx+1][0] 
    y2 = points[idx+1][1]

    rectangle.append(QgsPoint(x2,y2))

    #slope for first line
    m1 = (y2 - y1) / (x2 - x1)

    #intercept at origin for first line
    int1 = y1 - m1 * x1

    #slope for second line
    m2 = m1

    #x,y coordinates of third point
    x3 = points[idx+2][0] 
    y3 = points[idx+2][1]

    #intercept at origin for second line
    int2 = y3 - m2 * x3

    #first perpendicular
    m3 = -1/m1

    #intercept at origin for second line
    int3 = y2 - m3 * x2

    #intersect point
    x4 = (int3 - int2)/(m2 - m3)
    y4 = m3*x4 + int3

    rectangle.append(QgsPoint(x4, y4))

    #second perpendicular
    m4 = -1/m1

    #intercept at origin for second perpendicular
    int4 = y1 - m4 * x1

    #intersect point
    x5 = (int4 - int2)/(m2 - m4)
    y5 = m4*x5 + int4

    rectangle.extend([QgsPoint(x5, y5),QgsPoint(x1, y1)])

    polygon = []

    polygon.append(rectangle)

    geom = QgsGeometry.fromPolygon(polygon)

    feat = QgsFeature()

    feat.setAttributes([i])
    feat.setGeometry(geom)
    prov.addFeatures( [feat] )

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Lo probé con el shapefile de la siguiente imagen:

enter image description here

Después de ejecutar el código en la consola Python de QGIS que obtuve:

enter image description here

3voto

Diogenes Puntos 705

Puedes intentar usar el siguiente enfoque que cambia la geometría basada en el cuadro delimitador y el ángulo del primer borde digitalizado. Por supuesto, puedes alterar el ángulo con el del borde más largo o algo así. Sólo funciona bien cuando tus polígonos ya son casi rectangulares (como parece).

La entrada en la consola en Qgis y la capa debe ser seleccionada y editada:

import shapely

from shapely import affinity

from shapely.wkb import loads

layer = qgis.utils.iface.activeLayer()

for feature in layer.getFeatures():

    azimuth = feature.geometry().vertexAt(0).azimuth(feature.geometry().vertexAt(1))

    bbox = QgsGeometry.fromRect(feature.geometry().boundingBox())

    input = loads(bbox.asWkb())

    shape = shapely.geometry.asShape(input)

    rotated = affinity.rotate(shape, azimuth-90.0)

    new_geom = QgsGeometry.fromWkt(rotated.wkt)

    layer.changeGeometry(feature.id(),new_geom)

0voto

Jay Bazuzi Puntos 194

Para cada polígono de 4 vértices:

Calcule una estimación del centro del rectángulo, C, como la media de los 4 vértices.

Calcular una estimación de la longitud diagonal del rectángulo, R, como la media de las cuatro distancias desde el centro estimado hasta cada punto multiplicada por dos.

Calcular una estimación del ángulo de rotación del rectángulo tomando la media del ángulo de la línea entre los puntos 1 y 3 y entre los puntos 2 y 4. O posiblemente la media de (la media del ángulo entre (1 y C) y (C y 3)) y (la media del ángulo entre (2 y C) y (4 y C). Básicamente una estimación del ángulo a mitad de camino entre las dos diagonales.

Calcular la relación de aspecto del rectángulo calculando el promedio de los ángulos sin signo de una línea desde cada punto hasta el punto central y el ángulo de rotación. Así que si el rectángulo es cuadrado, esto es 45 grados.

Calcular los cuatro puntos a partir del conocimiento del centro, la longitud diagonal, la relación de aspecto y el ángulo de rotación.

Creo que esto es robusto para cualquier arreglo convexo de cuatro puntos... No sé qué podría hacer si se le da un polígono cóncavo...

Si hay alguna posibilidad de que puedas descargar tus datos de muestra, podría intentar codificar esto en ....

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