5 votos

Seleccione la parte más lejana del vértice del polígono del centro de gravedad utilizando ArcPy

Tengo un poligon y el polígono del centro de gravedad. Quiero seleccione la parte más lejana del vértice de centroide (foto: el punto a). He utilizado arcpy.FeatureVerticesToPoints_management para crear una clase de entidad que contiene los puntos generados a partir de un polígono, pero no sé qué hacer a continuación. ¿Podría usted ayudarme?

También quiero encontrar el punto de intersección (punto B) del contorno de polígono y línea creada por el centro de gravedad y el punto más distante (línea OA). enter image description here

Yo estaría muy agradecido por cualquier ayuda.

6voto

Marcin Puntos 11

Aquí está una pared abajo la versión de @crmackey la respuesta. La capa de polígono se llama 'POLY1", y debe ser la única cosa que usted necesita para cambiar, para conseguir una salida de archivo de punto más alejado de vértices - crea centroides sobre la marcha:

>>> points = []
>>> with arcpy.da.SearchCursor("POLY1",['SHAPE@']) as cursor:
...     for row in cursor:
...         centroid = row[0].centroid
...         dist = 0
...         for part in row[0]:
...             for pnt in part:
...                 cent_vert_dist = arcpy.PointGeometry(pnt).distanceTo(centroid)
...                 if cent_vert_dist > dist:
...                     dist = cent_vert_dist   
...                     far_point = arcpy.PointGeometry(pnt)
...         points.append(far_point)
...         
>>> arcpy.CopyFeatures_management(points,'in_memory\points')

Realizar un seguimiento de la intersección punto opuesto al vértice más alejado, es posible, pero requiere de algunas adicionales de la trigonometría que no estoy preparado para entrar en, cajero automático.

1voto

steveax Puntos 316

Esto funcionó para mí. El script crea una salida de clase de entidad de puntos que devuelve el punto que se encuentra más alejado del centro de gravedad para todos los polígonos:

import arcpy
import os
import sys
import traceback
import math
from datetime import datetime as d
arcpy.env.overwriteOutput = True

def Message(msg):
    print str(msg)
    arcpy.AddMessage(msg)

def findDistance(a,b):
    x = abs(a[0] - b[0])
    y = abs(a[1] - b[1])
    return math.sqrt((x*x) + (y*y))

def iter_geom(g):
    for i in xrange(g.partCount):
        yield i, g.getPart(i)

def polyPoints(in_polys, out_points):
    """function to find the minimum or maximimum distance between points

    Required:
        in_polys -- source points for near analysis
        out_points -- output nearest or farthest point from centroid
    """

    startTime = d.now()
    # grab xy coords
    point_dict, cent_dict = {}, {}
    with arcpy.da.SearchCursor(in_polys, ['OID@','SHAPE@']) as rows:
        for row in rows:
            points = []
            for i, part in iter_geom(row[1]):
                for pt in iter(lambda: part.next(), None):
                    points.append((pt.X, pt.Y))
            point_dict[row[0]] = points
            cent_dict[row[0]] = (row[1].centroid.X, row[1].centroid.Y)

    # grab attributes
    desc = arcpy.Describe(in_polys)
    fields = [f.name for f in desc.fields if not f.required]
    with arcpy.da.SearchCursor(in_polys, ['OID@'] + fields) as rows:
        att_dict = {r[0]: r[1:] for r in rows}



    # create dictionary to find nearest or farthest vertex from centroid
    newpt_dict = {}
    for oid, points in point_dict.iteritems():
        c = cent_dict[oid]
        dist_dict = {coords: findDistance(c,coords) for coords in points}
        query_pt = max(dist_dict.values())
        for k,v in dist_dict.iteritems():
            if v == query_pt:
                newpt_dict[oid] = (k, v)

    # create output table
    path, name = os.path.split(out_points)
    if arcpy.Exists(out_points):
        arcpy.Delete_management(out_points)
    sr = desc.spatialReference
    arcpy.CreateFeatureclass_management(path, name, 'POINT', in_polys, 'DISABLED', 'DISABLED', sr)
    arcpy.management.AddField(out_points, 'POLY_ID', 'LONG')
    arcpy.management.AddField(out_points,'POINT_DIST','DOUBLE')
    add_fields = ['POLY_ID', 'POINT_DIST']
    ifields = ['SHAPE@'] + fields + add_fields
    with arcpy.da.InsertCursor(out_points, ifields) as irows:
        for oid, pt_dist in newpt_dict.iteritems():
            all_atts = (pt_dist[0],) + att_dict[oid] + (oid, pt_dist[1])
            irows.insertRow(all_atts)
    Message('Created: %s' %os.path.basename(out_points))
    Message('(Elapsed time: %s)' %(str(d.now() - startTime)[:-3]))
    return out_points

if __name__ == '__main__':

##    # stand alone
    polys = r'C:\TEMP\Utility\Utilities.gdb\Parcels_small'
    out = polys + '_farPoints'
    polyPoints(polys, out)

0voto

FelixIP Puntos 4035

La Calculadora de campo de la versión.

  1. Agregar campos X e y a los polígonos de la tabla
  2. Ejecutar getFarPoint( !Shape!0) en el campo X
  3. Ejecutar getFarPoint( !Shape!1) en campo Y

bloque de código:

def getFarPoint(shp,n):
 p=shp.centroid
 g=arcpy.PointGeometry(p)
 l=shp.boundary()
 points=l.getPart(0)
 m=len(points); lMax=0.0
 for i in range(m):
  pN=points.getObject(i)
  d=g.distanceTo(pN)
  if d>lMax:
   lMax=d;pBest=pN
 pick=[pN.X,pN.Y]
 return pick[n]

Copia la tabla y crear puntos mediante Agregar eventos XY.

Le sugiero pedir una diferente Q en la segunda parte de su pregunta. Especificar si los polígonos son las mismas formas simples, como se muestra

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