更新:

是的,就是这样!

正如 mloskot 所说,整个表都需要被丢弃。使用 sql 选择字段会丢失有关字段宽度的信息。

谢谢,解决了!

大家好,

我有一个问题 奥格2奥格. 。我正在尝试将 PostgreSQL 表转储到 Shapefile。ogr2ogr 似乎改变了整数和字符等数据类型的大小。

以下是 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,211, ,字符长度来自 1080.

我读到,如果未指定宽度(长度),这些是默认值。

我如何指定宽度?

我尝试了每个带有或不带有铸造的组合,如下所示:

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 是在拉我的腿,但它显示了正确设置的 Shapefile 源 .dbf 的标题。

有人有什么想法吗?

埃杰

更新:嗨姆洛斯科特,

感谢您的回复和重新格式化,非常感谢!

我使用的是 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

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,我刚刚安装了它。

有帮助吗?

解决方案

首先,您没有指定您使用的 GDAL/OGR 版本,因此可能很难诊断问题出在哪里。请注意,各个版本都在应用改进。

是的,您的整数宽度和字符宽度分别是正确的值 11 和 80,是由设置的默认值 ESRI Shapefile 的 OGR 驱动程序

问题是您使用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 公用事业从 形状库. 。该软件使用与 GDAL/OGR 中使用的完全相同的 C 代码来处理 Shapefile 数据。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top