使用ArcPy或ModelBuilder移动/偏移点位置?


10

我有一些具有文本注释功能的非地理参考CAD图层(请参阅此问题)。我创建了一个模型,将文本转换为点,但是将注释转换为Point要素类后,我看到CAD文本锚点与CAD文本的中心(点所在的位置)不一致。

因此,我想以编程方式(使用ArcPy或ModelBuilder 使用将提供的X,Y值相对于其当前位置(delta x,y)[移动]特征

这将使我可以将GIS点移回它们所属的位置,而不是移到偏移的CAD锚点。

如何完成这项任务?


@PolyGeo 使用SHAPE @ XY IN 10.1 提供了一个很好的答案,但目前我正在运行10.0。有10.0个想法吗?

Answers:


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

有关阅读此书的任何人的类似过程的更多信息。仍然是10.1。 arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones

这实际上是在任何地方设置值吗?以前从未使用过UpdateCursor。通常,我会执行+ =,然后更新该行。否则,我在版本中唯一不同的是UpdateCursor使用['SHAPE @ X','SHAPE @ Y'],因此您可以将它们作为row [0]和row [1]进行访问,而不必执行row [0 ] [0]和第[0] [1]行。认为它对我来说更容易阅读。
eseglem

是的,这是更新行的有效方法。实际上,直到几周前我才看到过updateRow()中传递的值。它实际上是更新几何的一个示例。
保罗

非常感谢您的回答PolyGeo!实际上,我对代码进行了修改就印象深刻。我正在运行ArcGIS Desktop 10.6
Rie Mino'3

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

1
它应该是。只需将ShiftX和ShiftY参数分配给适当的列即可。
RyanKDalton '17

我对您在此处传递的“形状”感到困惑。你能帮我吗?
jbchurchill

“表达式”显示了正在传递到称为shiftXYCoordinates()的代码块函数中的参数。因此,第一个参数是!SHAPE !,它是图层的形状字段。
RyanKDalton '17

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坐标。
eseglem 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.