Добавление поля с именем файла при объединении шейп-файлов с ogr2ogr?

14

Я объединяю некоторые шейп-файлы, и у меня были некоторые проблемы с этим внутри QGIS, поэтому я использую ogr2ogr напрямую. Я делаю это (в партии):

ogr2ogr -overwrite %destination% %n1%
ogr2ogr -update -append %destination% %n2% -nln all_new
ogr2ogr -update -append %destination% %n3% -nln all_new
ogr2ogr -update -append %destination% %n4% -nln all_new

Он работает нормально, но теперь мне нужно иметь в результирующем шейп-файле поле с именами исходных шейп-файлов, которые я слил. Звучит не очень сложно, но мне не удается это сделать.

Кто-нибудь может помочь? Спасибо!

vascobnunes
источник

Ответы:

14

С небольшими сценариями это было бы выполнимо. Используя что-то вроде следующего, вы сможете добавить столбец в шейп-файл во все шейп-файлы в папке и объединить их в файл merged.shp

for %f in (*.shp) do (
  ogrinfo %f -sql "ALTER TABLE %f ADD COLUMN filename character(15)"
  ogrinfo %f -sql "UPDATE TABLE %f filename = '%f'"
  ogr2ogr -update -append merged.shp %f -f esri shapefile -nln merge 
)

edit: так же, как скрипт Bash, с некоторыми изменениями, чтобы он работал:

for f in *.shp
do 
  base=${f%.shp}
  ogrinfo $f -sql "ALTER TABLE $base ADD COLUMN filename character(15)"
  ogrinfo $f -dialect SQLite -sql "UPDATE $base SET filename = '$base'"
  ogr2ogr -update -append merged.shp $f
done
JaakL
источник
Это решение будет работать, только если все ваши слои / шейп-файлы имеют одинаковое имя, например, "CHEMIN" правильно? Я ищу решение для сценариев файлов с разными именами слоев.
oeon
Правильно, если вы замените CHEMIN на% f, он должен работать с любым именем, так как в таблице шейп-файлов имя является именем слоя. Я отредактировал ответ. У меня нет окон, чтобы проверить это действительно
JaakL
9

Я бы использовал опцию -sql и импортировал шейп-файл следующим образом:

ogr2ogr -update -append %destination% %n2% -sql 'SELECT "%n2%" as SHAPE_ORIG, field1, field2, ... FROM %n2%'
capooti
источник
Паоло - Я изо всех сил пытаюсь заставить это работать. Это можно сделать только с помощью ogr2ogr, а не ogrinfo? Я также писал в gdal-dev с моими примерами lists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html Не могу сделать это в Windows или Bash ..
oeon
Джо, единственная строка ogrinfo терпит неудачу, или она терпит неудачу только в контексте сценария (внутри цикла)?
capooti
Паоло - Я собираюсь добавить ответ, который работал для меня, ниже. Спасибо, что согласились со мной, добрый сэр! :)
oeon
7

Есть несколько способов объединения шейп-файлов.

  • если вы хотите объединить слои в один слой, вы можете использовать инструменты MMqgis для объединения ...

mmqgis

  • Если вы хотите объединить все шейп-файлы в папке, вы можете использовать простой код DARREN COPE здесь.

mkdir merged
for %f in (*.shp) do (
if not exist merged\merged.shp (
ogr2ogr -f esri shapefile merged\merged.shp %f) else (
ogr2ogr -f esri shapefile -update -append merged\merged.shp %f -nln Merged )
)
  • Кроме того, вы можете использовать бесплатный инструмент GeoMerge для объединения большого количества файлов, но не забывайте учитывать размер файла для работы с ним.

и добавление атрибута в шейп-файл @dango directon - это хорошо. Вы можете использовать layer.CreateField (field_name) для создания нового столбца, который заполняется из

import os
shapeFileName = os.path.splitext("your_shape_file_path")[0]

я надеюсь, что это поможет вам ...

Арагон
источник
5

vascobnunes, вот как я решил эту проблему, используя скрипт Python для последовательного объединения нескольких инструкций ogr2ogr. Вы можете легко преобразовать его в пакетный скрипт, в основном я просто объединяю инструкции ogr2ogr ( cmd), а затем выполняю их, вызывая os.system(cmd), передав команду ogr2ogr, которую я соединял вместе.

Секретным оружием является ( как продемонстрировал capooti ) применение OGR_SQL для наложения имени файла в качестве постоянного значения набора исходных данных, который вы добавляете в свой результат слияния.

В моем примере -sqlфлаг обрабатывает это, в коде это выглядит так:

-sql "SELECT \'' + filename + '\' AS filename, * FROM ' + filenameNoExt + '"'

Но это сбивает с толку, потому что мне нужно применять одинарные кавычки и двойные кавычки в результате объединения. Для этого мне нужно избегать одинарных кавычек (то есть \ '), чтобы использовать их «по-настоящему». Так что для удобства чтения, это помогает увидеть его без переменных и escape-последовательностей. Если вы делаете вид, что имя файла было «roads1» для конкретной итерации, результирующая конкатенация будет выглядеть следующим образом в предложении ogr2ogr:

-sql "SELECT 'roads1.shp' AS filename, * FROM roads1"

Этот скрипт .py представляет собой объединение трех трюков, которые я украл из matt wilkie (пустой клон шейп- файла ), j03lar50n (добавление столбца в шейп-файл с использованием ogrinfo и ogr_sql) и capooti (использование ogr_sql для наложения фиксированного значения столбца на всех записях в шейп-файле). Итак, вот полный сценарий:


# merge_shps.py
import os    

path = "D:/GIS/01_tutorials/ND_Roads/extracted"  # path to your folder of .shp files
merge = "merge_filename"                         # this will be the name of your merged result

directory = os.listdir(path)

count = 0
for filename in directory:
    if ".SHP" in filename.upper() and not ".XML" in filename.upper():

        # On the first pass, create a clone and add the filename column.
        if count == 0:
            # Make a clone (matt wilkie)..
            cmd = 'ogr2ogr ' + path + '/' + merge + '.shp ' + path + '/' + filename + ' -where "FID < 0"'
            os.system(cmd)

            # Add the field (j03lar50n)..
            cmd = 'ogrinfo ' + path + '/' + merge + '.shp -sql "ALTER TABLE ' + merge + ' ADD COLUMN filename character(50)"'
            os.system(cmd)

        # Now populate the data (capooti)..
        print "Merging: " + str(filename)

        # You'll need the filename without the .shp extension for the OGR_SQL..
        filenameNoExt = filename.replace(".shp","")

        cmd = 'ogr2ogr -f "esri shapefile" -update -append ' + \
                path + '/' + merge + '.shp ' + \
                path + '/' + filename + \
                ' -sql "SELECT \'' + filename + '\' AS filename, * FROM ' + filenameNoExt + '"'

        # Uncomment this line to spit the ogr2ogr sentence to the terminal..
        #print "\n" + cmd + "\n"

        os.system(cmd)

        count += 1
elrobis
источник
4

Добавить столбец с исходным именем файла из папки шейп-файлов. Требуется GDAL 1.10dev, моя попытка удалить расширение .shp не работает, но в целом работает. - Я полагаю, это можно добавить к строкам, которые объединяются с OGR.

for f in *.shp;

do

name=${f%.shp}

/Users/you/gdal_src/bin/ogrinfo $f -sql "ALTER TABLE $name ADD COLUMN filename character(21)"
/Users/you/gdal_src/bin/ogrinfo $f -dialect SQLite -sql "UPDATE $name SET filename = '$f'"
done;
oeon
источник
+1 за спецификацию диалекта. Я получил ошибки в верхнем ответе из-за того, что OGR SQL не обновлялся.
user15741
3

Привет, может быть, эта ссылка поможет. Он показывает, как добавить поле в шейп-файл, используя привязки Python GDAL.

данго
источник
2

Внутри QGIS вы можете добавить плагин Merge Shapefile. Есть опция «Добавить столбец с именем файла»введите описание изображения здесь

Райан Гарнетт
источник
Я получаю TypeError: объект типа 'NoneType' не имеет len ()
Ханнес Ледеген
0

Немного измененная версия ответа JaaKL. Обратите внимание, что -append foo.shp и -nln foo должны совпадать. Также обратите внимание на использование диалекта SQLite (GDAL, очевидно, не принимает ключевое слово «Update», поэтому необходимо использовать диалект SQLite) и отсутствие ключевого слова «TABLE» после слова «UPDATE» (не требуется). или приняты SQLite).

for %%f in (*.shp) do (
  if not "%%f" == "merge.shp" (
    ogrinfo %%f -sql "ALTER TABLE %%~nf ADD COLUMN fname character(15)"
    ogrinfo %%f -dialect SQLite -sql "UPDATE %%~nf SET fname = '%%~nf'"
    ogr2ogr -update -append merge.shp %%f -f "ESRI SHAPEFILE" -nln merge 
  )
)

источник
0

Немного опоздал к обсуждению, но теперь есть и огрмерге

ogrmerge.py -single -o merged.shp *.shp -src_layer_field_content {DS_BASENAME}
т книга
источник