ArcPy 또는 ModelBuilder를 사용하여 포인트 위치 이동 / 오프셋?


10

텍스트 주석 기능 이있는 지리 참조되지 않은 많은 CAD 레이어 ( 이 질문 참조 )가 있습니다. 텍스트를 점으로 변환하는 모델을 만들었지 만 주석을 점 피쳐 클래스로 변환 한 후 CAD 텍스트 앵커 포인트가 CAD 텍스트의 중심 (점이 속한 위치)과 일치하지 않는 것을 볼 수 있습니다.

그러므로, 나는 내가 제공 할 측정 된 X, Y 값을 사용하여 현재 위치 (델타 x, y)기준으로 지형지 물 을 프로그래밍 방식으로 (ArcPy 또는 ModelBuilder를 사용하여) [이동]하고 싶다.

이를 통해 오프셋 CAD 앵커 포인트 대신 GIS 포인트를 해당 위치로 다시 이동할 수 있습니다.

이 작업을 어떻게 수행 할 수 있습니까?


@PolyGeo는 SHAPE @ XY IN 10.1을 사용하여 훌륭한 대답 을 했지만 현재 10.0을 실행 중입니다. 10.0 아이디어가 있습니까?

답변:


17

이 코드는 ArcGIS 10.1에서 arcpy.da.UpdateCursor 와 함께 제공되는 SHAPE @ XY 토큰을 사용하여 수행해야합니다 .

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]])

여기에 사용 된 코딩 패턴은 ArcPy Café 에서 나왔습니다 .


어! 오늘 아침까지 SHAPE @ XY 는 10.1에서만 사용할 수 있으며 회사는 여전히 10.0을 사용하고 있음 을 깨닫게 되었습니다. 이것은 훌륭한 답변입니다 (앞으로). 나는 누군가가 10.0에 대한 제안이 있는지 기다릴 것입니다. 감사!
RyanKDalton

이것을 읽는 사람과 비슷한 과정에 대한 자세한 정보. 여전히 10.1입니다. arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones

이것은 실제로 어디에서나 값을 설정합니까? 이전과 같이 UpdateCursor를 사용한 적이 없습니다. 일반적으로 + =를 수행 한 다음 행을 업데이트합니다. 그렇지 않으면 내 버전에서 다르게하는 것은 UpdateCursor가 [ 'SHAPE @ X', 'SHAPE @ Y']를 사용하므로 행을 수행하지 않고 행 [0] 및 행 [1]으로 액세스 할 수 있다는 것입니다. ] [0] 및 행 [0] [1]. 나를 위해 조금 더 읽기 쉽다고 생각하십시오.
eseglem

예, 행을 업데이트하는 올바른 방법입니다. 실제로 몇 주 전까지 updateRow ()에 전달 된 값을 본 적이 없습니다. 실제로 형상을 업데이트하는 예제였습니다.
Paul

귀하의 답변 PolyGeo에 대해 대단히 감사합니다! 실제로 코드가 수정없이 작동한다는 사실에 꽤 감동했습니다.
Rie Mino

8

나는 나의 최종 솔루션으로 나를 이끌어 준 @ artwork21을 인정한다. ArcGIS 10.0 온라인 도움말에서 " 계산 예제 " 라는 거의 완전한 스크립트를 하위 범주 " 코드 샘플 — 지오메트리 "및 " 포인트 피쳐 클래스에 대해 각 포인트의 x 좌표를 100만큼 이동 "

ModelBuilder "Calculate Field"도구에서 사용한 마지막 스크립트는 다음과 같습니다.

표현:

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

여기서 ShiftXShiftY 는 ModelBuilder 캔버스에 정의 된 변수 (매개 변수)입니다.

발현 유형 :

PYTHON_9.3

코드 블록 :

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

모든 모델이 선택한 세트에서 작동하므로 다른 모델 작성기 세션에서 다른 모델 / 도구와 함께 작동하는 일반 도구로이 모델을 작성할 수도 있습니다. 내가 만든 매우 간단한 모델 (좌표 값을 이동하기위한 다른 모델의 "플러그인")은 다음과 같습니다. 이렇게하면 다른 모델에서 정의 된대로 선택 세트별로 시프트를 제어 할 수 있습니다.

ShiftXY 모델

그것은 매력처럼 작동했습니다. 입력 해 주셔서 감사합니다!


열에 저장된 테이블 내부의 값으로 기능을 이동할 수 있습니까?
Losbaltica

1
그것은해야한다. ShiftX 및 ShiftY 매개 변수를 해당 열에 지정하십시오.
RyanKDalton

나는 당신이 여기서 "모양"으로 전달하는 것에 혼란을 느낍니다. 도와주세요?
jbchurchill

"표현식"은 shiftXYCoordinates ()라는 코드 블록 함수로 전달되는 매개 변수를 보여줍니다. 따라서 첫 번째 매개 변수는! SHAPE!이며 레이어의 모양 필드입니다.
RyanKDalton

5

이 필드 계산기 스크립트 를 사용 하여 피처 위치를 이동할 수도 있습니다 .

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!)

위의 함수를 사용하여 모델 내에 추가 계산 필드 방법을 포함시킬 수 있습니다.


흥미로운 방법으로, 실제로 모양 필드에서 필드를 계산할 수 있다는 것을 몰랐습니다. 이것은 모든 점에 대해 설정된 오프셋 인 경우 실제로 수행하는 가장 쉬운 방법 일 수 있습니다. X 및 Y 좌표를 전달할 필요없이 point.X + = myMoveX 및 point.Y + = myMoveY를 수행하는 것이 더 빠를 것입니다.
eseglem

5

점을 특정 방향 (각도)과 주어진 거리로 이동 / 이동하도록 솔루션을 조정했습니다.

다음과 같습니다.

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

포인트 피처에 대한 필드“각도”(또는 상수)가있는 경우 shiftXYCoordinates (! SHAPE !,! Angle!, 5000)처럼 호출됩니다. 각도는 십진수로 주어져야합니다. 0은“위”, 90“오른쪽”등으로 이동합니다. 스트립 맵 인덱스 피처를 생성하고 포인트로 변환 한 후에 얻었습니다.

또한 실행하기 전에 필드 이름 "모양"을 선택해야합니다. :)

(ArcMap 10.0 SP5에서 테스트 된 솔루션)


4

보시다시피 커서 토큰에 액세스하면 10.1에서 훨씬 쉽습니다.

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

2

이것은 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.