Обсудить в форуме Комментариев 26Редактировать в вики
Перечь примеров для справки
С библиотекой gdal поставляется утилита ogr2ogr, предназначнная для конвертации векторных данных. В данной статье приводятся примеры использования этой утилиты.
GDAL/OGR - библиотека для работы с географическими форматами данных. GDAL представляет собой набор утилит для обработки растровых данных, в то время, как OGR предназначена для работы с векторными форматами. В статье рассматриваются некоторые практические примеры применения одной из утилит этой библиотеки: программы ogr2ogr. Примеры использования утилит для растровых данных приводятся в другой статье.
Программа ogr2ogr предназначена для конвертации векторных данных из одного формата в другой. Поддерживаемые форматы и используемые ключи можно узнать просто набрав в коммандной строке
ogr2ogr
В результате будет получена справка по использованию этой программы:
ogr2ogr [--help-general] [-skipfailures] [-append] [-update] [-gt n] [-select field_list] [-where restricted_where] [-sql ] [-spat xmin ymin xmax ymax] [-preserve_fid] [-fid FID] [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def] [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...] [-segmentize max_dist] dst_datasource_name src_datasource_name [-lco NAME=VALUE] [-nln name] [-nlt type] [layer [layer ...]]
А также список поддерживаемых форматов (список может отличаться как в большую, так и в меньшую сторону, поскольку зависит от того, были ли подключены/отключены соответствующие модули при компиляции программы):
Чтобы ogr2ogr корректно работал с файлами в названии которых есть кириллица, необходимо, перед выполнением команд установить переменную среды:
SET GDAL_FILENAME_IS_UTF8=OFF
Если исходные данные в кодировке UTF-8, то необходимо явным образом указывать, что выходные данные также будут в UTF-8, с помощью опции -lco ENCODING=UTF-8
, например:
ogr2ogr -lco ENCODING=UTF-8 output.shp input.vrt
Для ряда форматов через конфигурационные опции можно задать дополнительные настройки. Так, например, для формата SXF можно указать местоположение классификатора (файл RSC). Конфигурационные опции можно задавать через переменные окружения:
export SXF_RSC_FILENAME=map50.rsc
или в командной строке утилит (использование RSC из файла с другим именем):
ogrinfo --config SXF_RSC_FILENAME map50.rsc N-36-045.sxf
несколько опций задаются каждая со своим ключём (использование RSC из файла с другим именем и полные названия слоёв):
ogrinfo --config SXF_RSC_FILENAME map50.rsc --config SXF_LAYER_FULLNAME TRUE N-36-045.sxf
В примерах ниже будет использоваться shape-файл topo2km-rus.shp со следующими характеристиками:
Layer name: topo2km-rus Geometry: Polygon Feature Count: 10368 Extent: (-180.000000, 36.000000) - (180.000000, 88.000000) Layer SRS WKT: GEOGCS["GCS_Pulkovo_1942", DATUM["Pulkovo_1942", SPHEROID["Krasovsky_1940",6378245.0,298.3]], PRIMEM["Greenwich",0.0], UNIT["Degree",0.0174532925199433]] HEMISPHERE: String (1.0) INDEXROMAN: String (21.0) INDEXNUM: String (12.0) UNIQUE: String (25.0) ZONE: String (1.0) I10KM: Integer (4.0) I10KMZSTR: String (2.0) INDEXFULL: String (50.0) I2KM: Integer (4.0) I2KMZSTR: String (50.0)
Конвертировать ESRI Shapefile в формат MapInfo TAB можно следующим образом:
ogr2ogr -f "MapInfo File" topo2km-rus.tab topo2km-rus.shp
В результате в текущем каталоге появится 4 файла topo2km-rus.* --- результат конвертации.
Теперь конвертируем только некоторые объекты из файла topo2km-rus (в поле ZONE которых содержится строка "s"):
ogr2ogr -f "MapInfo File" -where "ZONE=s" topo2km-rus.tab topo2km-rus.shp
Аналогично можно воспользоваться параметрами:
-select для выбора определенных полей таблицы атрибутов. Например скопировать набор данных убрав все поля кроме name:
ogr2ogr -f GeoJSON -select name output.geojson input.geojson
Конвертация из CSV в shape-файл и обратно подробно рассмотрена в отдельной статье.
Существуют форматы позволяющие хранить несколько слоёв с разными геометриями. Например SXF. Для экстракции всех слоёв в формат ESRI Shape в качестве цели указывается папка, а не имя файла:
ogr2ogr output_dir input.sxf
Адресация конкретного слоя в таких наборах данных из нескольких слоёв адресация каждого слоя в этом случае осуществляется через пробел, например:
ogr2ogr output_dir input.sxf layer_name
Для форматов, которые позволяют хранить в одном слое сразу несколько типов геометрий нужен нестандартный подход, так, чтобы конвертировать MIF/MID в формат ESRI Shape нужно указать тип геометрии, например:
ogr2ogr -skipfailures input_POINT.shp input.mif -nlt "POINT"
или, чтобы получить все типы геометрий, можно использовать цикл (Windows):
for %n in (POINT POLYGON) do ogr2ogr -skipfailures output_%n.shp input.mif -nlt "%n"
Этот подход может не подойти, так как при конвертации может происходить конвертация типов геометрии, что приведет к появлению копии данных с другой геометрией. Например, такая команда:
ogr2ogr -skipfailures output_LINESTRING.shp input.mif -nlt "LINESTRING"
Приведет к созданию линейного shape-файла, несмотря на то, что в исходном файле вообще может не быть линий, а только полигоны. Следует отметить, что преобразования между одинаковыми типами с составными объектами, наоборот, не произойдет. Т.е. MULTILINESTRING не переведется в LINESTRING, а MULTIPOLYGON в POLYGON.
В связи с этим, более правильным подходом будет явным образом указать тип данных через -sql запрос, например:
ogr2ogr -skipfailures output_LINESTRING.shp input.mif -nlt "LINESTRING" -sql "SELECT * FROM Input WHERE OGR_GEOMETRY='LINESTRING'"
Полностью обработать данные для всех файлов с определенным расширением и всех типов геометрии можно так (цикл для командного интерпретатора Windows):
for %i in (*.mif) do for %n in (POINT LINESTRING POLYGON MULTIPOLYGON MULTIPOINT MULTILINESTRING) do ogr2ogr -skipfailures %~ni_%n.shp %i -nlt "%n" -sql "SELECT * FROM '%~ni' WHERE OGR_GEOMETRY='%n'"
В этом случае если в исходнике нет линий, то они не будут сконвертированы из полигонов, будет создан пустой shape-файл.
Можно построить и более сложные условия для выборки данных с помощью OGR SQL и параметра "-sql".
Выбрать при конвертации только объекты из таблицы "topo2km-rus", поле ZONE которых содержит 'PERVOMAYSK'
ogr2ogr -f "MapInfo File" -sql "SELECT * FROM topo2km-rus WHERE ZONE='PERVOMAYSK'" topo2km-rus.tab topo2km-rus.shp
Выбрать отдельные поля в определённом порядке:
ogr2ogr -f "MapInfo File" topo2km-rus.tab topo2km-rus.shp -sql "SELECT I2KMZSTR, I2KM, INDEXNUM FROM topo2km-rus)"
Выбрать и переименовать "на лету" отдельные поля в таблице
ogr2ogr -f "MapInfo File" topo2km-rus.tab topo2km-rus.shp -sql "SELECT I2KMZSTR AS 'i2kmzstr', I2KM AS '2km', INDEXNUM FROM topo2km-rus"
Сменить тип поля "на лету" у выбранных полей (можно совмещать смену полей с их переименованием)
ogr2ogr -f "MapInfo File" topo2km-rus.tab topo2km-rus.shp -sql "SELECT CAST (I10KM AS CHARACTER(4)), CAST (I2KM AS FLOAT) FROM topo2km-rus)"
Обратите внимание, что в SQL запросы не будут выполнены если в названиях файлов содержатся пробелы, знаки -. В этом случае название файла нужно брать в одинарные кавычки.
Значительно упростить команду можно использовав вместо ключа -sql ключ -where, его использование делает ненужным указание конструкции SELECT * FROM 'filename' WHERE
. Пример:
ogr2ogr -skipfailures output_MULTIPOINT.shp input.MIF -nlt "MULTIPOINT" -where "OGR_GEOMETRY='MULTIPOINT'"
вместо:
ogr2ogr -skipfailures output_MULTIPOINT.shp input.MIF -nlt "MULTIPOINT" -sql "SELECT * FROM input WHERE OGR_GEOMETRY='MULTIPOINT'"
Обратите внимание:
При выборке можно производить проверку значений на предмет равенства или неравенства:
ogr2ogr -sql "SELECT * FROM %~ni WHERE field1 NOT IN (0,12,13,15,16,254,255) AND field2 != -1" output.shp input.shp
Используя диалект SQLITE можно производить выборку определенного количества случайных точек:
ogr2ogr -sql "SELECT * FROM input WHERE field1 NOT IN (0,12,13,15,16,254,255) AND field2 != -1 ORDER BY RANDOM() LIMIT 10000" -dialect SQLITE output.shp input.shp
Добавить поле можно следующим образом (нового слоя не создаётся):
ogrinfo input.shp -sql "ALTER TABLE input ADD COLUMN newfield integer(3)"
Если нужно добавить значение в существующее поле, то нужна команда UPDATE, но она не поддерживается OGR SQL, поэтому нужно использовать диалект. Заполнить поле значениями можно вот так:
ogrinfo input.shp -dialect SQLite -sql "UPDATE input SET textfield = 'sometext'"
Драйвер SQLite должен быть скомпилирован с поддержкой диалекта SQLite SQL, иначе будет выводиться сообщение об ошибке: "ERROR 6: The SQLite driver needs to be compiled to support the SQLite SQL dialect".
Использование диалекта "SQLite" делает возможным применение огромного набора функций и операций, реализованной в данной СУБД, включая пространственное расширение "SpatiaLite". Например, операция по присвоению полю таблицы Mapinfo значения идентификатора UUID/GUID может быть легко реализована следующей командой:
ogrinfo -so myTab.TAB -dialect SQLite -sql "UPDATE myTab SET GLOBALID=CreateUUID()"
Используя ExecuteSQL можно выполнять и пространственные операции. Допустим есть два слоя - полигоны и точки и мы хотим посчитать количество точек в каждом полигоне.
Создаем файл vrt:
<OGRVRTDataSource> <OGRVRTLayer name="pol"> <SrcDataSource>pol.shp</SrcDataSource> <SrcLayer>pol</SrcLayer> </OGRVRTLayer> <OGRVRTLayer name="pnt"> <SrcDataSource>pnt.shp</SrcDataSource> <SrcLayer>pnt</SrcLayer> </OGRVRTLayer> </OGRVRTDataSource>
И выполним запрос с привлечением функции ST_Intesects:
ogrinfo -sql "SELECT COUNT(*) FROM pol, pnt WHERE ST_Intersects(pol.geometry,pnt.geometry) GROUP BY pol.id" -dialect SQLITE input.vrt
Если вам нужно просто перепрописать систему координат, без пересчета самого набора данных:
TODO
Для перевода данных из одной системы координат в другую могут использоваться следующие параметры:
Например, мы знаем, что файл topo2km-rus.shp содержит данные в географической системе координат Пулково 1942, но в комплекте с topo2km-rus.shp нет файла описания проекции (*.prj). Мы можем сгенерировать этот файл, воспользовавшись командой:
ogr2ogr -a_srs "EPSG:4284" -f "ESRI Shapefile" topo2km-rus2.shp topo2km-rus.shp
Команда:
ogr2ogr -s_srs "EPSG:4326" -t_srs "EPSG:900913" -f "ESRI Shapefile" topo2km-rus3.shp topo2km-rus2.shp
берет созданный на предыдущем этапе файл topo2km-rus2.shp и перепроецирует его в систему координат Google Mercator (epsg 900913), при этом опция -s_srs "epsg:4326" говорит о том, что при перепроецировании не нужно обращать внимания на исходную проекцию файла topo2km-rus2.shp, т.е. вести себя так, будто проекция источника - широта/долгота WGS84 (epsg 4326).
В приведенных примерах система координат указывалась на основе кодов epsg, но ее можно указывать и непосредственно в формате WKT или же передавать имя файла, в котором хранится ее описание. Например, если необходимо использовать описания систем координат, хранящихся в файлах input.prj и output.prj, то нужно использовать следующую конструкцию:
ogr2ogr -s_srs ESRI::Input.prj -t_srs ESRI::output.prj shapeout.shp shapein.shp
Перепроецировать данные с указанием набора параметров перехода из одной системы координат в другую можно следующим образом:
ogr2ogr -t_srs "+proj=latlong +ellps=krass +towgs84=23.92,-141.27,-80.9,0,0,0,0" shapeout.shp shapein.shp
Можно обрезать данные по нужному охвату, углы задаются в формате мин X, мин Y, макс X, макс Y.
ogr2ogr -clipsrc 41.4 46.4 41.6 46.6 output.shp input.shp
Вместо координат можно обрезать и по сложной форме заданной другим shape-файлом:
ogr2ogr -clipsrc clipbound.shp output.shp input.shp
пакетно (Win):
for %n in (*.shp) do ogr2ogr -clipsrc clipbound.shp output_folder/%n %n
пакетно (Ubuntu):
for f in *.shp; do ogr2ogr -lco ENCODING=UTF-8 -clipsrc clipbound.shp output_folder/${f} ${f}; done
Суть объединения по ogr'овски в том, что сначала создается копия первого источника данных, а потом к этой копии добавляются данные из второго, и т.д.
ogr2ogr result.shp input1.shp ogr2ogr -update -append result.shp input2.shp -nln result
В OGR можно использовать операцию JOIN:
ogr2ogr -sql "select input.*, table.* from input LEFT JOIN 'table.csv'.table ON input.id = table.IDINT" output.shp input.shp
В примере выше используется input.shp в качестве shape-файла и table.csv - в качестве присоединяемой таблицы. Присоединяемая таблица должна иметь расширение CSV. Обе таблицы разумеется должны иметь общее поле по которому будет происходить объединение, в данном случае это: id - поле в input.shp и IDINT - поле в table.csv. Ключом может быть и целочисленное и текстовое поле.
Следует учесть, в новом shape-файле названия полей будут изменены на новые, вида input.field1, input.field2,..., table.field1, table.field2 и т.д., т.е. в новой таблице названия полей будут указывать и источник. Так как существует ограничение на длину названия поля, то это может привести к ухудшению читаемости названия поля. Для начала можно укоротить названия входного shape-файла и таблицы и самих названий полей.
Более правильным решением является переназначение названий полей:
ogr2ogr -sql "select input.field1 AS FIELD1, table.field2 AS FIELD2 from input LEFT JOIN 'table.csv'.table ON input.id = table.IDINT" output.shp input.shp
Один из самых простых вариантов упрощения - отбрасывание разрядов значений координат после запятой. Ключ -lco COORDINATE_PRECISION=1
сколько оставить разрядов после запятой.
ogr2ogr -f "GeoJSON" -lco COORDINATE_PRECISION=1 output.json input.shp
Результирующие координаты будут приведены к форме DD.D, например: 75.158028 -> 75.200000, оставшиеся нули (если нужна минификация) нужно убирать уже в текстовом представлении, например таким регулярным выражением:
Find: "\.0([,\]])" Replace: "$1"
Вставка (добавление) записей в таблицу PostgreSQL данных из файла data.shp. Таблица должна существовать и иметь такие же поля, как и shp-файл.
ogr2ogr -append -t_srs "+init=epsg:4326" -f PostgreSQL PG:"host=адрес user=имя_пользователя dbname=имя_базы" data.shp
Перезаписывает test таблицу PostgreSQL данными из файла test.tab Таблица не обязана существовать.
ogr2ogr -append -overwrite -s_srs "+init=epsg:4326" -f PostgreSQL PG:"host=адрес user=имя_пользователя dbname=имя_базы" test.tab
Перезаписывает данные из файла data в таблицу PostgreSQL. Таблица будет носить имя не data, а test1. Таблица test1 не обязана существовать.
ogr2ogr -append -overwrite -t_srs "+init=epsg:4326" -f "PostgreSQL" PG:"host=адрес user=имя_пользователя dbname=test" data.shp -nln test1
Наоборот: из таблицы PostgreSQL "adm" базы ipc конвертирует в allei.tab формата MapInfo.
ogr2ogr -f "MapInfo File" allei.tab PG:"host=адрес user=пользователь dbname=ipc" "adm"
Из таблицы PostgreSQL "adm" базы ipc конвертирует в shape-файл с использованием выражения sql.
ogr2ogr -f "ESRi Shapefile" output.shp PG:"host=адрес user=пользователь dbname=ipc" -sql "SELECT * from adm"
Обсудить в форуме Комментариев 26Редактировать в вики
Последнее обновление: 2021-06-23 16:26
Дата создания: 21.07.2011 Автор(ы): Максим Дубинин
© GIS-Lab и авторы, 2002-2021. При использовании материалов сайта, ссылка на GIS-Lab и авторов обязательна. Содержание материалов - ответственность авторов. (подробнее).