ogr2ogr из PG в SHP меняет тип данных в .DBF - PullRequest
2 голосов
/ 02 февраля 2010

ОБНОВЛЕНИЕ:

Да, это было!

Как сказал mloskot, вся таблица должна быть сброшена. выбор полей с помощью sql теряет информацию о ширине фуилда.

Спасибо, что исправили!

Привет всем,

У меня проблема с ogr2ogr . Я пытаюсь вывести табель PostgreSQL в Shapefile. ogr2ogr, похоже, меняет размер типов данных, таких как integer и char.

Вот часть структуры БД, в которую был прочитан набор Shapefile:

Table "test"
nd_1 - numeric(8,0)
nd_2 - numeric(2,0)
nd_3 - numeric(2,0)
nd_9 - character varying(60)

и выглядит правильно.

Здесь начинается самое интересное:

ogr2ogr air5000.shp "PG: [...]" sql 'select
CAST(nd_1 AS INTEGER),
CAST(nd_2 AS INTEGER),
CAST(nd_3 as INTEGER),
CAST(ND_9 AS CHARACTER VARYING(60))
from test' ;

тогда

dbview -e test.dbf 

Field Name Type Length Decimal Pos
nd 1 - N - 11 - 0
nd 2 - N - 11 - 0
nd 3 - N - 11 - 0
nd 9 - C - 80 - 0

num-length идет от 8,2,2 до 11 , длина символа увеличивается от 10 до 80 .

Я прочитал, что это значения по умолчанию, если ширина (длина) не указана.

Как указать ширину?

Я пробовал каждую комбинацию с или без приведения, например:

select
CAST(nd_1 AS NUMERIC),
CAST(nd_2 AS NUMERIC),
CAST(nd_3 as NUMERIC),
CAST(ND_9 AS CHARACTER VARYING(60))

, что дает dbview:

Field Name Type Length Decimal Pos
nd 1 - N - 24 - 15
nd 2 - N - 24 - 15
nd 3 - N - 24 - 15
nd 9 - C - 80 - 0

без кастинга (select * from test) дает

Field Name      Type    Length  Decimal Pos
nd 1 - N - 24 - 15
nd 2 - N - 24 - 15
nd 3 - N - 24 - 15
nd 9 - C - 80 - 0

Нигде рядом с оригиналами.

debugfile [--debug on] ничего особенного не дает ИМХО, вот вывод команды 3 ogr2ogr, которую я пробовал:

PG: PQexec(DECLARE executeSQLCursor CURSOR for select CAST(nd_1 AS INTEGER), CAST(nd_2 AS INTEGER), CAST(nd_3 as INTEGER), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select CAST(nd_1 AS INTEGER), CAST(nd_2 AS INTEGER), CAST(nd_3 as INTEGER), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select CAST(nd_1 AS INTEGER), CAST(nd_2 AS INTEGER), CAST(nd_3 as INTEGER), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: 2 features read on layer 'sql_statement'.

PG: PQexec(DECLARE executeSQLCursor CURSOR for select CAST(nd_1 AS NUMERIC), CAST(nd_2 AS NUMERIC), CAST(nd_3 as NUMERIC), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select CAST(nd_1 AS NUMERIC), CAST(nd_2 AS NUMERIC), CAST(nd_3 as NUMERIC), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select CAST(nd_1 AS NUMERIC), CAST(nd_2 AS NUMERIC), CAST(nd_3 as NUMERIC), CAST(ND_9 AS CHARACTER VARYING(60)) from test)
PG: 2 features read on layer 'sql_statement'.
PG: PQexec(DECLARE executeSQLCursor CURSOR for select * from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select * from test)
PG: PQexec(DECLARE OGRPGResultLayerReader CURSOR for select * from test)
PG: 2 features read on layer 'sql_statement'.

Я тоже попробовал -dsco precision=no, но это тоже не помогло.

Возможно, dbview тянет меня за ногу, но он показывает, что заголовок исходного файла .dbf Shapefile установлен правильно.

У кого-нибудь есть идеи?

EJ

Обновить: привет, млоскот,

спасибо за ваш ответ и переформатирование, высоко ценится!

Я нахожусь на GDAL 1.6.3.

Я пытался указать ширину, но это не имеет значения.

ogr2ogr test.shp "PG: [...] " -sql 'select CAST(nd_1 AS INTEGER), CAST(nd_2 AS numeric(2,0)), CAST(nd_3 as NUMERIC(2,0)) from test' ;

дает:

Field Name  Type    Length  Decimal Pos
nd 1          N    11       0
nd 2          N    24      15
nd 3          N    24      15

да, я попытался указать поля без приведения, например:

ogr2ogr air5000.shp "PG: [...] "-sql 'select nd_1, nd_2, nd_3, ND_9 from test'

, что дает:

 Field Name Type    Length  Decimal Pos
nd 1          N    24      15
nd 2          N    24      15
nd 3          N    24      15
nd 9          C    80       0

1089 * пытается *

integer(field_length)

как

CAST(nd_2 AS INTEGER(2))

не работает, выдает ошибку

ERROR 1: ERROR: current transaction is aborted, commands ignored until end of transaction block

может быть, мои версии Postgresql и PostGIS датированы? Postgres = 8,3,5, PostGIS = 1,3,3

Я проверю Shapelib, я установил его только сейчас.

1 Ответ

5 голосов
/ 03 февраля 2010

Во-первых, вы не указываете, какую версию GDAL / OGR вы используете, поэтому может быть сложно определить причину проблемы. Обратите внимание, что улучшения применяются от версии к версии.

Да, вы используете правильные значения 11 и 80 для целочисленной ширины и ширины символа соответственно. Это значения по умолчанию, установленные Драйвером OGR для шейп-файла ESRI

Проблема в том, что вы используете SQL-запрос для выборки только некоторых строк из таблицы форм и это вызывает OGR PG драйвер драйвер не сохраняет ширину поля.

Сравните эти два выхода:

Запрос всей таблицы

$ ogrinfo PG:dbname=test test_ogr
Layer name: test_ogr
Geometry: Point
Feature Count: 1
Extent: (1.000000, 2.000000) - (1.000000, 2.000000)
Layer SRS WKT:
(unknown)
FID Column = id
Geometry Column = geom
n3: String (60.0)
n1: Integer (8.0)
n2: Integer (2.0)
OGRFeature(test_ogr):1
  n3 (String) = abcdefg
  n1 (Integer) = 12345678
  n2 (Integer) = 12
  POINT (1 2)

Тот же запрос, но с указанным вручную SQL, выберите

$ ogrinfo PG:dbname=test -sql "SELECT n1, n2, n3, geom FROM test_ogr"
Layer name: sql_statement
Geometry: Unknown (any)
Feature Count: 1
Extent: (1.000000, 2.000000) - (1.000000, 2.000000)
Layer SRS WKT:
(unknown)
Geometry Column = geom
n1: Real (0.0)
n2: Real (0.0)
n3: String (0.0)
OGRFeature(sql_statement):0
  n1 (Real) = 12345678
  n2 (Real) = 12
  n3 (String) = abcdefg
  POINT (1 2)

Как видите, второй вариант полностью теряет свойства поля, и именно так работает OGR.

Вот тот же пример двух выходных данных, но с переводом в Shapefile:

Сброс всех данных из test_ogr таблицы

$ ogr2ogr -f "ESRI Shapefile" test.shp PG:dbname=test test_ogr
$ dbfdump -h test.dbf
Field 0: Type=C/String, Title=`n3', Width=60, Decimals=0
Field 1: Type=N/Integer, Title=`n1', Width=8, Decimals=0
Field 2: Type=N/Integer, Title=`n2', Width=2, Decimals=0
n3                                                                 n1 n2
abcdefg                                                      12345678 12

С использованием опции -sql и запроса SELECT:

$ ogr2ogr -f "ESRI Shapefile" test.shp PG:dbname=test -sql "SELECT n1, n2, n3, geom FROM test_ogr"
$ dbfdump -h test.dbf
Field 0: Type=N/Double, Title=`n1', Width=24, Decimals=15
Field 1: Type=N/Double, Title=`n2', Width=24, Decimals=15
Field 2: Type=C/String, Title=`n3', Width=80, Decimals=0
                      n1                       n2 n3
12345678.000000000000000       12.000000000000000 abcdefg

Итак, чтобы точно сохранить все свойства, вам нужно вывести всю таблицу без указания SQL-запроса.

Кстати, если вы подозрительно относитесь к dbfview, вы можете попробовать проверить свои выходные файлы Shapefile (.shp, .dbf) с помощью shpdump и dbfdump из Shapelib . Это программное обеспечение использует точно такой же код C, который используется в GDAL / OGR для обработки данных Shapefile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...