Przenoszenie / przesunięcie lokalizacji punktów za pomocą ArcPy lub ModelBuilder?

10

Mam wiele niereferencyjnych warstw CAD (patrz to pytanie ), które mają funkcje adnotacji tekstu. Stworzyłem model do konwersji tekstu na punkty, ale po przekonwertowaniu adnotacji na klasę Punktów widzę, że punkty kontrolne tekstu CAD nie pokrywają się ze środkiem tekstu CAD (do którego należą punkty).

Dlatego chciałbym programowo (przy użyciu ArcPy lub ModelBuilder) [przenieść] funkcję względem jej bieżącej lokalizacji (delta x, y) przy użyciu zmierzonej wartości X, Y, którą podam.

Pozwoliłoby mi to przenieść punkty GIS z powrotem do miejsca, w którym należą, zamiast przesuniętego punktu kontrolnego CAD.

Jak mogę wykonać to zadanie?


@ PolyGeo udzielił doskonałej odpowiedzi za pomocą SHAPE @ XY IN 10.1, ale obecnie korzystam z wersji 10.0. Jakieś pomysły 10.0?

RyanKDalton
źródło

Odpowiedzi:

17

Ten kod powinien to zrobić przy użyciu tokena SHAPE @ XY dostarczonego z arcpy.da.UpdateCursor w ArcGIS 10.1.

import arcpy
# Set some variables
fc = r"C:\temp\test.gdb\testFC"
fc2 = r"C:\temp\test.gdb\testFCcopy"
xOffset = 0.001
yOffset = 0.001
# Code to make a copy which will have its coordinates moved (and can be compared with original)
if arcpy.Exists(fc2):
    arcpy.Delete_management(fc2)
arcpy.Copy_management(fc,fc2)
# Perform the move
with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        cursor.updateRow([[row[0][0] + xOffset,row[0][1] + yOffset]])

Zastosowany tutaj wzór kodowania pochodzi z ArcPy Café .

PolyGeo
źródło
Ugh! Dopiero dziś rano zdałem sobie sprawę, że SHAPE @ XY jest dostępny tylko w wersji 10.1, a moja firma nadal korzysta z wersji 10.0. To świetna odpowiedź (w przyszłości), ale poczekam i zobaczę, czy ktoś ma jakieś sugestie dotyczące wersji 10.0. Dzięki!
RyanKDalton
Więcej informacji na temat podobnego procesu dla każdego, kto to czyta. Wciąż 10.1. arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones
Czy to faktycznie ustawia wartości gdziekolwiek? Nigdy wcześniej nie korzystałem z UpdateCursor w taki sposób. Zwykle robię + =, a następnie aktualizuję wiersz. W przeciwnym razie jedyną rzeczą, którą robię inaczej w mojej wersji, jest to, że UpdateCursor używa [„SHAPE @ X”, „SHAPE @ Y”], abyś mógł uzyskać do nich dostęp jako wiersz [0] i wiersz [1] zamiast robić wiersz [0 ] [0] i wiersz [0] [1]. Pomyśl, że jest to dla mnie trochę łatwiejsze do odczytania.
eseglem
Tak, to poprawny sposób na aktualizację wierszy. W rzeczywistości nigdy nie widziałem wartości przekazywanej w updateRow () jeszcze kilka tygodni temu. Był to w rzeczywistości przykład aktualizacji geometrii.
Paul
Dziękuję bardzo za odpowiedź PolyGeo! Byłem pod wrażeniem, że kod działał bez modyfikacji. Korzystam z ArcGIS Desktop 10.6
Rie Mino
8

Podziękowania dla @ artwork21 za doprowadzenie mnie do mojego ostatecznego rozwiązania. Właściwie znalazłem prawie kompletny skrypt w artykule pomocy online ArcGIS 10.0 „ Oblicz przykłady pola ”, wymienionym w podkategorii „ Próbki kodu - geometria ” i „ W przypadku klasy obiektów punktowych przesunąć współrzędną x każdego punktu o 100

Ostatnim skryptem, którego użyłem w narzędziu Model Caluate „Calculate Field” było:

Wyrażenie:

shiftXYCoordinates(!SHAPE!,%ShiftX%,%ShiftY%)

gdzie ShiftX i ShiftY są zmiennymi (jako parametrami) zdefiniowanymi na kanwie ModelBuilder.

Typ wyrażenia:

PYTHON_9.3

Blok kodu:

def shiftXYCoordinates(shape,x_shift,y_shift):
   point = shape.getPart(0)
   point.X += float(x_shift)
   point.Y += float(y_shift)
   return point

Ponieważ wszystkie modele działają na wybranym zestawie, powinieneś być w stanie stworzyć to jako ogólne narzędzie, które będzie działało w połączeniu z innymi modelami / narzędziami w innych sesjach konstruktora modeli. Bardzo prosty model, który stworzyłem (jako „wtyczka” do innych modeli w celu przesunięcia wartości współrzędnych) wygląda następująco. W ten sposób mogę kontrolować zmianę na podstawie zestawu wybranych elementów (jak zdefiniowano w innych modelach):

Model ShiftXY

Działa jak urok, dziękuję wszystkim za wkład!

RyanKDalton
źródło
czy możliwe jest przesunięcie funkcji o wartość wewnątrz tabeli, zapisaną w kolumnie?
Losbaltica
1
Powinno być. Po prostu przypisz parametry ShiftX i ShiftY do odpowiednich kolumn.
RyanKDalton
Jestem zdezorientowany tym, co tu podajesz jako „kształt”. Czy możesz mi pomóc, proszę?
jbchurchill
„Wyrażenie” pokazuje parametry, które są przekazywane do funkcji bloku kodu o nazwie shiftXYCoordinates (). Tak więc pierwszym parametrem jest! SHAPE !, czyli pole kształtu z warstwy.
RyanKDalton
5

Możesz także użyć tego skryptu kalkulatora pola, aby przenieść lokalizacje obiektów:

def XYsetVALUE( shape, X_value, Y_value): 
  myMoveX = 0.001
  myMoveY = 0.001
  point = shape.getPart(0) 
  point.X = X_value + myMoveX
  point.Y = Y_value + myMoveY
  return point 

XYsetVALUE (! SHAPE !,! X_COORD !,! Y_COORD!)

Możesz włączyć dodatkową metodę obliczania pola w swoim modelu, korzystając z powyższej funkcji.

grafika 21
źródło
To ciekawy sposób, aby to zrobić, tak naprawdę nie wiedziałem, że możesz obliczyć pole na polu kształtu. Może to być najłatwiejszy sposób, aby to zrobić, jeśli jest to ustawione przesunięcie dla wszystkich punktów. Prawdopodobnie szybsze byłoby wykonanie point.X + = myMoveX i point.Y + = myMoveY zamiast konieczności podawania współrzędnych X i Y.
eseglem
5

Dostosowałem rozwiązanie, aby przesunąć / przesunąć punkty w określonym kierunku (kącie) i na określoną odległość.

Wygląda jak:

def shiftXYCoordinates(shape,angle,distance):
point = shape.getPart(0)
point.Y += distance * math.cos(math.radians(angle))
point.X += distance * math.sin(math.radians(angle))
return point

i nazywamy się jak shiftXYCoordinates (! SHAPE !,! Angle!, 5000), jeśli masz „kąt” pola dla cech punktów (lub ze stałą oczywiście). Kąt należy podawać w stopniach dziesiętnych. 0 przesunie „w górę”, 90 „w prawo” itd. Mam je po utworzeniu funkcji indeksu map paskowych i przekonwertowaniu ich na punkty.

Upewnij się także, aby przed uruchomieniem wybrać nazwę pola „Kształt” :)

(Rozwiązanie przetestowane w ArcMap 10.0 SP5)

kgl
źródło
4

Jak widać, w 10.1 jest o wiele łatwiej, gdy masz dostęp do tokenów kursora.

import arcpy
# Code to move features in copy of same dataset
fc = r"C:\temp\test.gdb\testFC"
fc2 = r"C:\temp\test.gdb\testFCcopy"
xOffset = 0.001
yOffset = 0.001
if arcpy.Exists(fc2):
    arcpy.Delete_management(fc2)
arcpy.Copy_management(fc, fc2)

shape = arcpy.Describe(fc2).ShapeFieldName

cursor = arcpy.UpdateCursor(fc2)
for row in cursor:    
    point = row.getValue(shape).getPart()
    row.setValue(shape, arcpy.Point(point.X + xOffset, point.Y + yOffset))
    cursor.updateRow(row) 

del point, row, cursor
Paweł
źródło
2

Działa to dla 10.0:

# Featureclass here
FC = r'featureclass'

fcount = 0
shapefield = arcpy.Describe(FC).shapeFieldName
featureUpdate = arcpy.UpdateCursor(FC)
for f in featureUpdate:
    # Hard coded shifts but easy enough to set up a lookup function if needed
    sLon = 0.001
    sLat = 0.001
    # Optional but I like to count to see where it is at in the process
    if fcount % 1000 == 0:
        print('Updating feature %s...' %(fcount))
    # Get the original value
    cF = f.getValue(shapefield)
    cPNT = cF.getPart()
    # Create a new point with the shifted value
    sPNT = arcpy.Point(cPNT.X - sLon, cPNT.Y - sLAT)
    # Set the shapefield to the new point and update feature
    f.setValue(shapefield, sPNT)
    featureUpdate.updateRow(f)
    fcount += 1
del featureUpdate
eseglem
źródło