Modification du chemin de la source de données impliquant un jeu de données d'entité dans des fichiers * .lyr à l'aide d'ArcPy?

11

Comment peut-on changer les chemins de données source pour chaque fichier de couche dans le dossier X en utilisant arcpy?

J'ai suivi la mise à jour et la correction des sources de données avec arcpy.mapping du mieux que je peux, mais tout ce que je reçois est une aide inutile Runtime error <type 'exceptions.ValueError'>: Layer: Unexpected errorqui ne me dit pas assez pour résoudre ce qui ne va pas ou ce qui manque.

Voici le code (simplifié pour tester un fichier monocouche):

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

et les résultats:

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

((déplacé la section «mise à jour» dans une réponse))

Matt Wilkie
la source
le Runtime error...cité ci-dessus est du shell python interactif dans Arccatalog, qui ne donne pas de trace. Les résultats avec traceback sont copiés à partir d'un shell de commande.
Matt Wilkie
1
Déplacez-vous des données dans ou hors d'un jeu de données d'entité ainsi que d'un espace de travail?
geographika
@geographika: oui le FDS change ainsi que l'espace de travail. J'ai été induit en erreur par la documentation qui dit de ne pas spécifier le FDS, et que les mxd et les lyr les ignorent. Valider d'autre part ne les ignore pas, ou du moins pas complètement (voir ma réponse).
matt wilkie

Réponses:

7

Il semble que la méthode correcte à utiliser lors du changement d'espaces de travail ET de jeux de données d' entités soit lyr.replaceDataSource () . Voici mon script de travail:

''' 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

Lors des tests, il semble que la validation dans cette méthode soit à nouveau différente: elle vérifie que le nouvel espace de travail est valide, mais ignore la classe d'entités et les ensembles de données d'entités - ce qui signifie qu'il ne renverra pas d'erreur si le FC cible n'est pas là.

D'un autre côté, si le FC cible est présent, même à l'intérieur d'un jeu de données d'entité différent, le nouveau chemin de source de données est adapté en conséquence, que la validation soit vraie ou fausse.

Mise à jour: maintenant sur Github pour permettre un partage et une révision plus faciles.

Matt Wilkie
la source
Est-ce que cela fonctionne lorsque je veux remplacer un fichier shp source .lyr par un nouveau? J'obtiens ValueError: Layer: Erreur inattendue.
GeorgeC
@GeorgeC - Je sais que c'est un ancien article, mais si quelqu'un le trouve via le moteur de recherche, la solution à cette erreur est susceptible de supprimer le .shp du nom de l'ensemble de données. IOW le troisième argument pour remplacerDataSource doit être "newfile" et non "newfile.shp"
perrygeo
6

L'inutile unexpected errordans ce cas signifie quelque chose comme "le nouveau chemin n'existe pas" . Le validateparamètre facultatif par défaut est True s'il n'est pas spécifié. Avec false, le script se termine sans erreur, mais les fichiers de couche résultants étaient toujours rompus même si le chemin de destination et la classe d'entités existent.

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

résultat

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

En plus de ne pas savoir initialement valider par défaut sur true, un bogue ou au moins un comportement très original a rendu le dépannage difficile. La mise à jour et la correction des sources de données avec arcpy.mapping indique Ne pas inclure les noms des jeux de données d'entité dans le chemin de l'espace de travail. Les jeux de données d'entité font partie de l'espace de travail. Si une classe d'entités, par exemple, passe d'une classe d'entités autonome à un jeu de données d'entités, un document ArcMap s'ouvrira toujours sans que la couche ne soit rompue " et " Si une couche ou un tableau dans un document ArcMap ou un fichier de couches est déplacé dans ou hors d'un jeu de données d'entité, leurs liens ne doivent pas être rompus. "

Il s'avère que valider a un angle légèrement différent à ce sujet. Oui, peu importe où se trouve dans la nouvelle géodatabase (espace de travail) la classe d'entités cible , au niveau supérieur ou dans un jeu de données d' entités complètement différent. Cependant, l'espace de travail cible doit contenir un jeu de données d'entité portant le même nom ou la validation échoue .

Couches cassées et "fixes", telles qu'elles apparaissent dans Arccatalog et Arcmap

Sources :

Matt Wilkie
la source