Использование ArcPy для определения версии документа ArcMap?

21

Есть ли способ с ArcPy определить версию документа карты (MXD). Я работаю над решением для инвентаризации наших MXD и хотел бы знать, является ли документ 8.1, 9.2, 10.0 и т. Д.

В настоящее время я использую ArcGIS 10.0, но если в 10.1 будет обновление, которого нет в 10.0, я был бы также признателен за это.

Я вижу, что есть предыдущий вопрос: Как вы можете найти версию ArcGIS программно? , но он ссылается на все решения ArcObjects (которые, я полагаю, я мог бы вызвать из python , но я бы предпочел не делать этого).

RyanKDalton-OffTheGridMaps
источник
2
Я думаю, что для этого может потребоваться запрос улучшения для свойства версии, доступного только для чтения, для добавления в объект MapDocument. Если вы найдете / создадите его, то сделайте ссылку на него здесь, и я буду голосовать за него.
PolyGeo
Есть контроль версий ArcGis Idea. (ну 3 слились в одну)
gm70560
Я скопировал ваш сценарий, слегка изменил его для своей среды и запустил на некоторых моих файлах, но некоторые файлы не вернули версию, хотя я знаю, что они были сохранены в 9.3 или 10.0. Я не уверен, что испорченные источники данных испортят ваш сценарий.
Связанный: gisnuts.com/terra/blog/2014/02/24/… Отличная находка @danjurgell в комментарии к последующему вопросу к принятому ответу здесь. Исходя из этого сообщения в блоге, нет 100% надежного способа сделать это, потому что информация просто не сохраняется в файле предсказуемым образом. Оба ответа здесь будут работать иногда, но не всегда .
Крис W

Ответы:

23

Я знаю, что этому вопросу уже несколько месяцев, но я публикую его на тот случай, если он поможет другим. Я разработал этот ключ для анализа номеров версий из документов MXD. Он в основном читает первые 4000 или около того символов документа MXD и ищет номер версии. Я тестировал с MXD версий 9.2, 9.3, 10.0 и 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

Вот пример сканирования папки для файлов mxd и печати версии и имен

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

Что возвращает это:

>>> 
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
>>>
Райан С.
источник
Это очень круто! Очень полезный. Теперь мы можем сделать это также со слоями и базами геоданных?
Майк
Это чисто потрясающе!
Дчабоя
Работа до 10.4 Я анализирую mxd с помощью Hexa Reader и меняем положение версии (это после пути до и сегодня до пути и добавляем префикс "Build Number", значение слова следующее - (10.4.0.5524). С 10.3.1 I имеют значение 10.3.6 в гекса-значении
GeoStoneMarten
1
мне кажется, это не работает, проверяя 10.6.1 mxds, которые были сохранены в 10.2.2 (все возвращаемые «версия не может быть определена») ... были ли какие-либо обновления в mxd docs для интеграции в этот скрипт?
JasonBK
14

Приведенная ниже функция основана на идее Райана, но немного более прямолинейна. Документы карты ArcGIS на самом деле являются документами OLE, которые можно проанализировать с помощью oletoolsмодуля (доступно на pypi: https://pypi.python.org/pypi/oletools ). Функция открывает файл и читает строку версии. Протестировано с 9.0, 9.3, 10.1 и 10.3, но должно работать с чем угодно (не уверен насчет 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
источник
1
Это тоже отличная функция. Единственное сомнение, которое я бы испытывал против использования этой функции, заключается в том, что она требует от пользователя загрузки / установки сторонней библиотеки (oletools), что в некоторых организациях пользователи не могут сделать.
RyanKDalton-OffTheGridMaps
Я получаю только один голос, но это сработает в тех случаях, когда другой ответ не дает.
DWynne
Snorfalorpagus хорошо работает до 10.3, но для 10.4 есть другой ключ потока «Mx Document Version Info» с полной версией номера сборки. Я проверил с другой версией arcgis, и моя последняя версия вернула 10.4.0.5524
GeoStoneMarten
Интересный. Я еще не обновился до 10.4. Не могли бы вы поделиться пустым MXD для меня, чтобы увидеть?
Снорфалорпагус
1
@GeoStoneMarten Спасибо. Я посмотрел на документ, который вы отправили. Кажется, он работает с оригинальным кодом - я не вижу поток "Mx Document Version Info"?
Снорфалорпагус