Перемещение / смещение точек с помощью ArcPy или ModelBuilder?

10

У меня есть несколько слоев САПР без географической привязки (см. Этот вопрос ), которые имеют функции текстовых аннотаций. Я создал модель для преобразования текста в точки, но после преобразования аннотации в класс пространственных объектов Point я вижу, что точки привязки текста САПР не совпадают с центром текста САПР (в котором эти точки принадлежат).

Поэтому я хотел бы программно (используя ArcPy или ModelBuilder) [переместить] объект относительно его текущего местоположения (дельта x, y), используя измеренное значение X, Y, которое я предоставлю.

Это позволило бы мне переместить точки ГИС обратно туда, где они принадлежат, вместо смещенной точки привязки САПР.

Как я могу выполнить эту задачу?


@PolyGeo дал отличный ответ, используя SHAPE @ XY IN 10.1, но в настоящее время я использую 10.0. Любые 10.0 идей?

RyanKDalton
источник

Ответы:

17

Этот код должен делать это с помощью токена SHAPE @ XY, поставляемого с arcpy.da.UpdateCursor в 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]])

Шаблон кодирования, использованный здесь, взят из ArcPy Café .

PolyGeo
источник
Тьфу! До сегодняшнего утра я понял, что 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] вместо того, чтобы выполнять строку [0 ] [0] и строка [0] [1]. Думаю, мне легче читать.
Eseglem
Да, это правильный способ обновления строк. На самом деле, я никогда не видел значение, переданное в updateRow (), до нескольких недель назад. Это был пример обновления геометрии.
Пол
Большое спасибо за ваш ответ PolyGeo! Я был действительно впечатлен тем, что код работал без изменений. Я использую ArcGIS Desktop 10.6
Rie Mino
8

Я благодарен @ artwork21 за то, что он привел меня к окончательному решению. На самом деле я нашел почти полный скрипт в статье интерактивной справки ArcGIS 10.0 под названием « Вычислить примеры полей », перечисленной в подкатегориях « Образцы кода - геометрия » и « Для класса точечных объектов сдвиньте координату x каждой точки на 100 »

Последний скрипт, который я использовал в инструменте «Вычислить поле» из ModelBuilder, был:

Выражение:

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

где ShiftX и ShiftY - переменные (как параметры), определенные на холсте 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

Это сработало как шарм, спасибо всем за ваш вклад!

RyanKDalton
источник
Можно ли сместить объект на значение внутри таблицы, хранящейся в столбце?
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!)

Вы можете включить дополнительный метод Calculate Field в вашу модель, используя функцию выше.

artwork21
источник
Это интересный способ сделать это, я на самом деле не знал, что вы можете вычислить поле формы. На самом деле это может быть самый простой способ сделать это, если это заданное смещение для всех точек. Вероятно, было бы быстрее сделать point.X + = myMoveX и point.Y + = myMoveY вместо того, чтобы передавать координаты X и Y для него.
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
eseglem
источник