¿Usa ArcPy para determinar la versión del documento de ArcMap?

21

¿Hay alguna manera con ArcPy para identificar la versión de un documento de mapa (MXD)? Estoy trabajando en una solución para inventariar nuestros MXD y me gustaría saber si un documento es 8.1, 9.2, 10.0, etc.

Actualmente estoy usando ArcGIS 10.0, pero si hay una actualización en 10.1 que no existe en 10.0, agradecería escuchar eso también.

Veo que hay una pregunta anterior de ¿Cómo puede encontrar la versión de ArcGIS mediante programación? , pero hace referencia a todas las soluciones de ArcObjects (que supongo que podría llamar desde python , pero preferiría no hacerlo).

RyanDalton
fuente
2
Creo que esto podría necesitar una solicitud de mejora para que se agregue una propiedad de versión de solo lectura al objeto MapDocument. Si encuentra / crea uno, enlace a él aquí y votaré por él.
PolyGeo
Hay una versión de control de ArcGis Idea. (bueno, 3 fusionados en uno)
gm70560
Copié su script, lo modifiqué un poco para mi entorno y lo ejecuté en algunos de mis archivos, pero algunos de los archivos no devolvieron una versión aunque sé que se guardaron en 9.3 o 10.0. No estoy seguro de si las fuentes de datos dañadas estropearían su secuencia de comandos.
Relacionado: gisnuts.com/terra/blog/2014/02/24/… Un excelente hallazgo de @danjurgell en un comentario sobre una pregunta de seguimiento a la respuesta aceptada aquí. Según esa publicación de blog, no existe una forma 100% confiable de hacer esto porque la información simplemente no se almacena en el archivo de manera predecible. Ambas respuestas funcionarán algunas veces, pero no todo el tiempo.
Chris W

Respuestas:

23

Sé que esta pregunta tiene unos meses, pero la publico en caso de que ayude a otros. Desarrollé este kludge para analizar los números de versión de los documentos MXD. Básicamente, lee los primeros 4000 caracteres de un documento MXD y busca un número de versión. Probé con las versiones MXD 9.2, 9.3, 10.0 y 10.1.

import re

def getMXDVersion(mxdFile):
    matchPattern = re.compile("9.2|9.3|10.0|10.1|10.2")
    with open(mxdFile, 'rb') as mxd:
        fileContents = mxd.read().decode('latin1')[1000:4500]
        removedChars = [x for x in fileContents if x not in [u'\xff',u'\x00',u'\x01',u'\t']]
        joinedChars = ''.join(removedChars)
        regexMatch = re.findall(matchPattern, joinedChars)
        if len(regexMatch) > 0:
            version = regexMatch[0]
            return version
        else:
            return 'version could not be determined for ' + mxdFile

Aquí hay un ejemplo de escaneo de una carpeta para archivos mxd e impresión de la versión y los nombres

import os
import glob
folder = r'C:\Users\Administrator\Desktop\mxd_examples'
mxdFiles = glob.glob(os.path.join(folder, '*.mxd'))
for mxdFile in mxdFiles:
    fileName = os.path.basename(mxdFile)
    version = getMXDVersion(mxdFile)
    print version, fileName

Lo que devuelve esto:

>>> 
10.0 Arch_Cape_DRG.mxd
9.2 class_exercise.mxd
9.3 colored_relief2.mxd
10.1 CountyIcons.mxd
10.0 DEM_Template.mxd
9.2 ex_2.mxd
10.0 nairobimap.mxd
10.0 slope_script_example.mxd
10.1 TrailMapTemplateBetter.mxd
10.0 Wickiup_Mountain_DEM.mxd
>>>
Ryan S.
fuente
¡Esto es muy genial! Muy útil. ¿Ahora podemos hacer esto también con capas y geodatabases?
Mike
¡Esto es puramente asombroso!
dchaboya
Trabaje bien antes de 10.4 He analizado mxd con el lector Hexa y la posición de la versión ha cambiado (es después de la ruta antes y hoy es antes de la ruta y agrego el valor de las palabras del prefijo "Número de compilación" a continuación es (10.4.0.5524). Con 10.3.1 I tener 10.3.6 en parte de valor hexa
GeoStoneMarten
1
esto no parece funcionar para mí, verificando 10.6.1 mxds que se han guardado en 10.2.2 (no se pudo determinar la 'versión no se pudo determinar') ... ¿ha habido actualizaciones en los documentos mxd para integrarlos en este script?
JasonBK
14

La función a continuación se basa en la idea de Ryan, pero es un poco más directa. Los documentos de mapa de ArcGIS son en realidad documentos OLE, que se pueden analizar con el oletoolsmódulo (disponible en pypi: https://pypi.python.org/pypi/oletools ). La función abre el archivo y lee la cadena de versión. Probado con 9.0, 9.3, 10.1 y 10.3, pero debería funcionar con cualquier cosa (no estoy seguro acerca de 3.x ...).

from oletools.thirdparty import olefile

def mxd_version(filename):
    ofile = olefile.OleFileIO(filename)
    stream = ofile.openstream('Version')
    data = stream.read().decode('utf-16')
    version = data.split('\x00')[1]
    return version

if __name__ == '__main__':
    import sys
    print(mxd_version(sys.argv[-1]))
Snorfalorpagus
fuente
1
Esa también es una gran función. La única duda que tendría contra el uso de esta función es que requiere que el usuario descargue / instale una biblioteca de terceros (oletools) que en algunas organizaciones los usuarios no pueden hacer.
RyanDalton
Solo obtengo un voto, pero esto funcionará en los casos en que la otra respuesta no.
DWynne
Snorfalorpagus funciona bien hasta 10.3, pero para 10.4 hay otra clave de flujo 'Mx Document Version Info' con la versión completa del número de compilación. Lo comprobé con una versión diferente de arcgis y mi última versión regresó el 10.4.0.5524
GeoStoneMarten
Interesante. No he actualizado a 10.4 todavía. ¿Podrías compartir un mxd en blanco para que lo vea?
Snorfalorpagus
1
@GeoStoneMarten Gracias. He mirado el documento que enviaste. Parece que funciona con el código original. ¿No veo la secuencia "Mx Document Version Info"?
Snorfalorpagus