Mer

Parvis (lineær) avstand mellom punkter i samme formfil


Gitt et sett med punkter som representerer landsbyer som er lagret i en .shp-fil, er det en måte å beregne den parvise avstanden (euklidisk) mellom dem? Det jeg ønsker å komme med er en slags symmetrisk matrise som skal analyseres ytterligere statistisk.

Jeg bruker ArcGIS 10.1 med en avansert lisens.


Alternativt kan du bruke verktøyet Generer nær bord til å gjøre det samme som GISGes forslag, men med noen ekstra attributter (for eksempel xy av nærfunksjonen og vinkelen mellom kilde- og nærfunksjoner) hvis de ville være nyttige i studien din. Den lar deg også angi et antall nærmeste kamper, så det er ikke alt eller bare nærmeste.


Bruk verktøyet Punktavstand til å gjøre dette, med punktformfilen som inndatafunksjoner og nærfunksjonsparametere.


Beklager, jeg ville svare på tidligere kommentarer, men jeg har ikke 50 poeng på profilen min (nytt medlem), og jeg blir blokkert. Siden funksjonsklassene "Input" og "Near" begge er de samme, hvorfor ikke lage en kopiere av din originale FC og bruke originalen som "Input" og kopien som "Nær" for verktøyet? Dette kan omgå problemene du har med å bruke samme funksjonsklasse som Input/Near.

Nærverktøyene og Point Distance -verktøyene krever en avansert lisens, så det ser ut til at du har det nødvendige lisensnivået. For de som har Basic/Standard, er ESRIs Near -algoritme ikke så vanskelig å implementere deg selv i Python. Dette svaret ligner på det jeg la ut i Beregn nærmeste avstand i ArcView, XY -koordinater. Men siden du vil alle parvis sammenligninger (ikke bare den nærmeste funksjonen), vil verktøyet lage en tabell med alle parvise sammenligninger. Det vil også opprette en "loddlinjer" -funksjonsklasse som forbinder alle par og har samme informasjon som tabellen (denne utgangen er mer nyttig IMO). For mål- og kilde -ID -feltene kan du bruke "OBJECTID" eller en hvilken som helst annen unik ID du ønsker. Det vil fungere på alle lisensnivåer. Hvis du ikke har flaks med forslagene ovenfor, kan du prøve dette skriptet.

__author__ = "John K. Tran" __contact__ = "[email protected]" __version__ = "1.0" __created__ = "7/1/15" "" "Sammenligner alle målpunktfunksjoner med alle kildepunktfunksjoner og fyller ut ID -en og avstanden for alle parvise sammenligninger mellom hvert mål til hver kilde. Kan eventuelt opprette loddlinjer for å visualisere koblingene mellom kilde- og målfunksjoner. "" "import arcpy import os import math import random arcpy.SetProgressor (" Standard "," Firing up script ... ") # Sett opp innledende parametere for script. source = arcpy.GetParameterAsText (0) # Point funksjonsklasse. target = arcpy.GetParameterAsText (1) # Point funksjonsklasse. outputtable = arcpy.GetParameterAsText (2) # Tabellfunksjonsklasse som lagrer avstands- og ID -informasjon. sourceIDfield = arcpy.GetParameterAsText (3) # Felt for å identifisere unik ID for kildeverdier. targetIDfield = arcpy.GetParameterAsText (4) # Felt for å identifisere unik ID for målverdier. createplumblines = arcpy.GetParameterAsText (5) # Valgfritt utgangssted for loddlinjer. Foreslår på det sterkeste at du angir en bane for dette! arcpy.env.parallelProcessingFactor = "100%" #Convert arcpy field types for "Field Type" argument in AddField_management. fieldtypedict = {"Blob": "BLOB", "Date": "DATE", "Double": "DOUBLE", "Guid": "GUID", "Integer": "LONG", "Raster": "RASTER" , "Single": "FLOAT", "SmallInteger": "SHORT", "String": "TEXT", "OID": "LONG"} # Få felttypen for kilde -ID -feltet, så vi kan lage et analogt felt for NearID i målet. sourcefields = arcpy.ListFields (source) targetfields = arcpy.ListFields (target) sourceIDfieldtype = fieldtypedict [[field.type for field in sourcefields if field.name == sourceIDfield] .pop ()] targetIDfieldtype = fieldtypedict [[field.type for feltet i målfelt hvis feltet.navn == targetIDfield] .pop ()] # Få de romlige referansene for kilde og mål, og kontroller at de er like. sourcespatialref = arcpy.Describe (source) .spatialReference goalspatialref = arcpy.Describe (target) .spatialReference assert sourcespatialref.name == goalspatialref.name, "Kilden og målet må ha samme koordinatsystem. Sørg for at begge dataene er i et identisk projisert. koordinatsystem." # Lag en poengklasse med en avstandsmetode. Mer effektiv enn native arcpy.Geometry -klasse. class Point (objekt): def __init __ (self, x, y, ID): "" "Lag konstruktøren for å initialisere punktet." "" self.x = x self.y = y self.ID = ID def GetDist ( self, OtherPoint): "" "Bestemmer avstanden mellom to punkter ved hjelp av Pythagorean Theorem." "" return math.sqrt ((self.x-OtherPoint.x) ** 2+ (self.y-OtherPoint.y) ** 2) # Lag en liste over kildepunkter for å sammenligne med hvert målpunkt. scount = 0 sourcepoints = list () med arcpy.da.SearchCursor (kilde, ["[email protected]", sourceIDfield]) som kildeforløper: for rad i sourcecursor: arcpy.SetProgressorLabel ("Gathering Source Points: {0} features complete" .format (str (scount))) sourcepoint = Point (rad [0] [0], rad [0] [1], rad [1]) sourcepoints.append (sourcepoint) scount += 1 del sourcecursor # Lag flere oppstart variabler hvis oppretting av loddlinjer var aktivert. if createplumblines: arcpy.SetProgressorLabel ("Making Plumb Line Feature Class") plumblines = list () arcpy.CreateFeatureclass_management (os.path.dirname (createplumblines), os.path.basename (createplumblines), "POLYLINE", None, "DISABLED "," DISABLED ", goalspatialref) arcpy.AddField_management (createplumblines," SourceID ", sourceIDfieldtype) arcpy.AddField_management (createplumblines," TargetID ", targetIDfieldtype) # Lag en tabell for å lagre avstandsinformasjon. arcpy.SetProgressorLabel ("Making Distance Table") arcpy.CreateTable_management (os.path.dirname (outputtable), os.path.basename (outputtable)) arcpy.AddField_management (outputtable, "SourceID", sourceIDfieldtype) arcpy.AddField_management, "TargetID", targetIDfieldtype) arcpy.AddField_management (outputtable, "Distance", "DOUBLE") # Lag en liste for å lagre hver sammenligning, slik at vi kan legge den til i tabellen etterpå. distlist = [] # Gå gjennom hvert mål og sammenlign med hver kilde og fyll ut ID- og avstandsfelt i tabellen. count = 0 med arcpy.da.SearchCursor (target, ["[email protected]", targetIDfield]) som targetcursor: for rad i targetcursor: arcpy.SetProgressorLabel ("Computing Distance: {0} features complete" .format (str (count ))) targetpoint = Point (rad [0] [0], rad [0] [1], rad [1]) for sourcepoint i sourcepoints: currentdist = targetpoint.GetDist (sourcepoint) distlist.append ((sourcepoint.ID, targetpoint.ID, currentdist)) if createplumblines: plumblines.append ((sourcepoint, targetpoint)) count = count + 1 del targetcursor # Oppdater tabellen med informasjonen fra distlisten. tnum = 0 with arcpy.da.InsertCursor (outputtable, ["SourceID", "TargetID", "Distance"]) as tablecursor: for row in distlist: arcpy.SetProgressorLabel ("Legger til avstander i tabellen: {0} funksjoner fullført" .format (str (tnum))) tablecursor.insertRow (row) del tablecursor # Lag loddlinjene hvis alternativet var aktivert. hvis createplumblines: plnum = 0 plumbcursor = arcpy.da.InsertCursor (createplumblines, ["[email protected]", "SourceID", "TarIDID"]) for sourcepnt, targetpnt i plumblines: arcpy.SetProgressorLabel ("Genererer loddlinjer: {0} har komplett ".format (str (plnum))) plumbarray = arcpy.Array ([arcpy.Point (sourcepnt.x, sourcepnt.y), arcpy.Point (targetpnt.x, targetpnt.y)]) plumbline = arcpy. Polyline (plumbarray) plumbcursor.insertRow ((plumbline, sourcepnt.ID, targetpnt.ID)) plnum += 1 del plumbcursor # Ferdig! arcpy.ResetProgressor ()

Gi meg beskjed hvis du har problemer med å kjøre skriptet. Det fungerer for punkt-til-punkt geometri sammenligninger. En mer utfordrende øvelse er å skrive en algoritme for å sammenligne de høyere geometypene med hverandre.

Lykke til!


Se videoen: Matematikk R2 Formel for avstand mellom punkt og plan i rommet (Oktober 2021).