Изменение пути к источнику данных с использованием набора классов объектов в файлах * .lyr с использованием ArcPy?

11

Как можно изменить пути к исходным данным для каждого файла слоя в папке X, используя arcpy?

Я следил за обновлением и исправлением источников данных с помощью arcpy.mapping, насколько я могу, но все, что я получаю, - это бесполезное, Runtime error <type 'exceptions.ValueError'>: Layer: Unexpected errorкоторое не говорит мне достаточно, чтобы решить, что не так или отсутствует.

Вот код (упрощенный для тестирования однослойного файла):

import arcpy, os

fname = r'K:\Layers\xxx.lyr'
lyr = arcpy.mapping.Layer(fname)
oldpath = lyr.workspacePath
print 'oldpath: ', oldpath
lyr.findAndReplaceWorkspacePath(oldpath, r'C:\some\other.gdb')
print 'newpath: ', lyr.workspacePath

и результаты:

oldpath:  K:\Canvec_Utility\Temp.gdb
Traceback (most recent call last):
  File "x10x.py", line 12, in <module>
    lyr.findAndReplaceWorkspacePath(oldpath, r'C:\some\other.gdb')
  File "C:\ESRI\ArcGIS\Desktop10.0\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\ESRI\ArcGIS\Desktop10.0\arcpy\arcpy\_mapping.py", line 601, in findAndReplaceWorkspacePath
    return convertArcObjectToPythonObject(self._arc_object.findAndReplaceWorkspacePath(*gp_fixargs((find_workspace_path, replace_workspace_path, validate), True
)))
ValueError: Layer: Unexpected error

((перенес раздел «обновить» в ответ))

Мэтт Уилки
источник
Runtime error...цитировал выше из интерактивной оболочки Python в ARCCATALOG, который не дает отслеживающий. Результаты с трассировкой копируются из командной оболочки.
Мэтт Уилки
1
Вы перемещаете данные в набор классов объектов, а также в рабочее пространство?
география
@geographika: да, FDS меняется так же, как и рабочее пространство. Я был введен в заблуждение документацией, в которой говорится , не указывайте FDS, и что mxd и lyr игнорируют их. Validate, с другой стороны, не игнорирует их или, по крайней мере, не полностью (см. Мой ответ).
Мэтт Уилки

Ответы:

7

Похоже, правильный метод для использования при переключении рабочих пространств и наборов классов объектов - lyr.replaceDataSource () . Вот мой рабочий скрипт:

''' Change the datasource path for the given layer file '''

import arcpy, os

# layer file to re-path
fname = arcpy.GetParameterAsText(0)
# new path to workspace containing the feature class
target_wspace = arcpy.GetParameterAsText(1)
# where to save the layer files
savedir = arcpy.GetParameterAsText(2)

lyr = arcpy.mapping.Layer(fname)

fixed_fname = os.path.join(savedir, lyr.longName)

print '\nOld layer properties (%s)' % (fname)
print 'workspace:\t', lyr.workspacePath
print 'full path:\t', lyr.dataSource

try:
    lyr.replaceDataSource(target_wspace, 'FILEGDB_WORKSPACE', lyr.datasetName, True)
    lyr.saveACopy(fixed_fname)
except:
    print arcpy.GetMessages()

print '\nNew layer properties (%s)' % (fixed_fname)
print 'workspace:\t', lyr.workspacePath
print 'full path:\t', lyr.dataSource

del lyr

При тестировании кажется, что validate в этом методе снова отличается: он проверяет, что новое рабочее пространство является действительным, но игнорирует класс пространственных объектов и наборы классов объектов - то есть не возвращает ошибку, если целевой FC отсутствует.

С другой стороны, если целевой FC присутствует, даже в другом наборе классов объектов, новый путь источника данных соответствующим образом адаптируется независимо от того, является ли validate истинным или ложным.

Обновление: теперь на Github, чтобы облегчить обмен и редактирование.

Мэтт Уилки
источник
Работает ли это, когда я хочу заменить исходный shp-файл .lyr на новый? Я получаю ValueError: Layer: неожиданная ошибка.
GeorgeC
@ GeorgeC - я знаю, что это старый пост, но в случае, если кто-то найдет его через поисковую систему, решение этой ошибки, скорее всего, удалит .shp из имени набора данных. IOW третий аргумент для замены DataSource должен быть "newfile", а не "newfile.shp"
perrygeo
6

Бесполезный unexpected errorв данном случае означает что-то вроде «новый путь не существует» . Необязательный validateпараметр по умолчанию равен True, если не указан. При значении false сценарий завершается без ошибок, но полученные файлы слоев по-прежнему были повреждены, хотя целевой путь и класс объектов существуют.

...    
lyr.findAndReplaceWorkspacePath(oldpath, r'C:\some\other.gdb', False)
...

результат

oldpath:  K:\code\Canvec\Scripts\Temp.gdb
newpath:  C:\some\other.gdb

В дополнение к изначально незнанию validate по умолчанию true, ошибка или, по крайней мере, какое-то очень странное поведение затрудняют устранение неполадок. Обновление и исправление источников данных с помощью arcpy.mapping говорит : не включайте имена наборов классов объектов в путь к рабочей области. Наборы классов объектов являются частью рабочей области. Например, если класс пространственных объектов перенесен из автономного класса пространственных объектов в набор классов объектов, документ карты все равно будет открыт без разрыва слоя » и « Если слой или таблица в документе карты или файле слоя » перемещены в набор классов объектов или из него, их ссылки не должны быть разорваны. "

Оказывается, у validate немного другой угол. Да, не имеет значения, где в новой базе геоданных (рабочем пространстве) находится целевой класс объектов , на верхнем уровне или в совершенно другом наборе классов объектов. Однако целевое рабочее пространство должно содержать набор классов объектов с тем же именем, иначе проверка не удалась .

Разбитые и «фиксированные» слои, как они выглядят в Arccatalog и Arcmap

Источники :

Мэтт Уилки
источник