ArcPyまたはModelBuilderを使用してポイントの位置を移動/オフセットしますか?


10

テキスト注釈機能を持つ、地理参照されていないCADレイヤー(この質問を参照)がいくつかあります。テキストをポイントに変換するモデルを作成しましたが、アノテーションをポイントフィーチャクラスに変換した後、CADテキストのアンカーポイントがCADテキストの中心(ポイントが属する場所)と一致しないことがわかります。

したがって、プログラムで(ArcPyまたはModelBuilderを使用して)提供するX、Yの測定値を使用して、現在の位置(デルタx、y)基準にフィーチャを移動します。

これにより、オフセット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]])

ここで使用されているコーディングパターンは、ArcPyCaféのものです。


うわっ!SHAPE @ XYは10.1でのみ利用可能であり、私の会社はまだ10.0を使用していることに気づくのに今朝までかかりました。これは素晴らしい答えです(これから先)。でも、10.0について何か提案があるかどうか待ってみます。ありがとう!
RyanKDalton 2013

これを読んでいる人のための同様のプロセスに関する詳細情報。それでも10.1 arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones 2013

これは実際にどこかに値を設定していますか?これまでにそのようなUpdateCursorを使用したことはありません。通常、+ =を実行してから、行を更新します。それ以外の場合、私のバージョンで異なるのはUpdateCursorが['SHAPE @ X'、 'SHAPE @ Y']を使用することだけなので、行[0]および行[1]としてアクセスできます。行[0]を実行する必要はありません。 ] [0]および行[0] [1]。私にとっては少し読みやすいと思います。
エセレム2013

はい、これは行を更新する有効な方法です。実際、数週間前までupdateRow()で渡される値を見たことがありませんでした。これは実際にはジオメトリを更新するための例でした。
ポール

あなたの答えPolyGeoをどうもありがとう!実際、コードを変更せずに機能することにかなり感銘を受けました。私はArcGIS Desktop 10.6を実行しています
Mino

8

私の最終的なソリューションに導いてくれた@ artwork21に感謝します。私は実際に「と呼ばれるのArcGIS 10.0のオンラインヘルプ記事でほぼ完全なスクリプトを発見した計算フィールドの例のサブカテゴリ」の下にリストされている「サンプルコード-ジオメトリー」と「ポイントフィーチャクラスの場合、xは100で、各点の座標シフト

ModelBuilderの「フィールドの計算」ツールで使用した最後のスクリプトは次のとおりです。

式:

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 2017

1
そのはず。ShiftXパラメータとShiftYパラメータを適切な列に割り当てるだけです。
RyanKDalton 2017

ここで「形」として渡されているものに混乱しています。手伝ってくれませんか?
jbchurchill 2017年

「式」は、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!)

上記の関数を使用して、モデル内に追加のフィールド計算メソッドを含めることができます。


これは興味深い方法です。実際に、シェイプフィールドでフィールド計算できるとは知りませんでした。これは、すべてのポイントに設定されたオフセットである場合、実際にそれを実行する最も簡単な方法です。しかし、point.X + = myMoveXとpoint.Y + = myMoveYを実行する方が、X座標とY座標を渡す必要がなく、高速です。
エセレム2013

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は「右」などにシフトします。ストリップマップインデックスフィーチャを作成し、それらをポイントに変換した後に取得しました。

また、実行する前にフィールド名「Shape」を選択してください:)

(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.