Usando o ArcPy para determinar a versão do documento do ArcMap?

21

Existe uma maneira do ArcPy identificar a versão de um documento de mapa (MXD). Estou trabalhando em uma solução para inventariar nossos MXDs e gostaria de saber se um documento é 8.1, 9.2, 10.0 etc.

Atualmente, estou usando o ArcGIS 10.0, mas se houver uma atualização na 10.1 que não exista na 10.0, eu gostaria de ouvir isso também.

Vejo que há uma pergunta anterior de Como você pode encontrar a versão do ArcGIS programaticamente? , mas faz referência a todas as soluções ArcObjects (que eu suponho que poderia chamar de python , mas preferiria não).

RyanDalton
fonte
2
Eu acho que isso pode precisar de uma solicitação de aprimoramento para que uma propriedade de versão somente leitura seja adicionada ao objeto MapDocument. Se você encontrar / criar um, vincule-o aqui e votarei nele.
PolyGeo
Existe um controle de versão do ArcGis Idea. (bem, 3 mesclados em um)
gm70560
Copiei seu script, modifiquei-o levemente para o meu ambiente e executei-o em alguns dos meus arquivos, mas alguns deles não retornaram uma versão, mesmo sabendo que eles foram salvos nas 9.3 ou 10.0. Não tenho certeza se fontes de dados quebradas atrapalhariam seu script.
Relacionado: gisnuts.com/terra/blog/2014/02/24/… Uma excelente descoberta por @danjurgell em um comentário em uma pergunta de acompanhamento da resposta aceita aqui. Com base nessa postagem do blog, não há uma maneira 100% confiável de fazer isso, porque as informações simplesmente não são armazenadas no arquivo de maneira previsível. Ambos respostas aqui vai trabalhar algum do tempo, mas não todo o tempo.
Chris W

Respostas:

23

Sei que essa pergunta tem alguns meses, mas estou postando isso para ajudar outras pessoas. Eu desenvolvi esse kludge para analisar os números de versão dos documentos MXD. Ele basicamente lê os primeiros 4000 caracteres de um documento MXD e procura um número de versão. Eu testei com as versões 9.2, 9.3, 10.0 e 10.1 do MXD.

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

Aqui está um exemplo de digitalização de uma pasta para arquivos mxd e impressão da versão e nomes

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

O que retorna isso:

>>> 
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.
fonte
Isso é muito legal! Muito útil. Agora também podemos fazer isso com camadas e bancos de dados geográficos?
Mike
Isso é incrível!
precisa saber é o seguinte
Trabalhe bem antes da versão 10.4 Eu analisei o mxd com o leitor Hexa e a posição da versão mudou (é após o caminho antes e hoje é antes do caminho e adicione "Build Number"). tem 10.3.6, em parte, valor hexa
GeoStoneMarten
1
isso parece não funcionar para mim, verificando 10.6.1 mxds que foram salvos novamente em 10.2.2 (todo o retorno 'versão não pôde ser determinada') ... houve alguma atualização nos documentos mxd para integrar neste script?
JasonBK 18/09
14

A função abaixo é baseada na ideia de Ryan, mas é um pouco mais direta. Os documentos de mapa do ArcGIS são na verdade documentos OLE, que podem ser analisados ​​com o oletoolsmódulo (disponível em pypi: https://pypi.python.org/pypi/oletools ). A função abre o arquivo e lê a string da versão. Testado com 9.0, 9.3, 10.1 e 10.3, mas deve funcionar com qualquer coisa (não tenho certeza sobre 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
fonte
1
Essa é uma ótima função também. A única hesitação que eu teria contra o uso dessa função é que ela requer que o usuário baixe / instale uma biblioteca de terceiros (oletools) que, em algumas organizações, os usuários podem não conseguir.
RyanDalton
Eu recebo apenas um voto, mas isso funcionará nos casos em que a outra resposta não.
DWynne
Snorfalorpagus funciona bem até 10.3, mas para 10.4 existe uma outra chave de fluxo 'Mx Document Version Info' com a versão completa do número de compilação. Eu verifiquei com versão diferente do ArcGIS e minha última versão retorno 10.4.0.5524
GeoStoneMarten
Interessante. Ainda não atualizei para 10.4. Você poderia compartilhar um MXD em branco para eu ver?
Snorfalorpagus 03/05/19
1
@GeoStoneMarten Thanks. Eu olhei para o documento que você enviou. Parece funcionar com o código original - não vejo o fluxo "Mx Document Version Info"?
Snorfalorpagus