[gdal-dev] Determining Native Data Field Type Names for a Given Layer or Driver

Even Rouault even.rouault at spatialys.com
Wed Sep 27 03:48:22 PDT 2017


On mardi 26 septembre 2017 17:16:28 CEST Andrew Joseph wrote:
> I'm using the GDAL Java Bindings (most recent dev version 2.3.0) and looking
> to determine the native datatype of a given layer field -or at least the
> default mapping of the driver. For example I have manually written code
> like the following for Postgres/Postgis:
> 
>   private static final BiMap<String,Integer> PG_OGR_GOMETRY_TYPE_MAP =
>       new ImmutableBiMap.Builder<String, Integer>()
>         .put("Point",wkbPoint)
>         .put("LineString",wkbLineString)
>         .put("Polygon",wkbPolygon)
>         .put("Surface",wkbSurface)
>         .put("Curve",wkbCurve)
>         .put("MultiPoint",wkbMultiPoint)
>         .put("MultiLineString",wkbMultiLineString)
>         .put("MultiPolygon",wkbMultiPolygon)
>         .put("GeometryCollection",wkbGeometryCollection)
>         .put("CircularString",wkbCircularString)
>         .put("CompoundCurve",wkbCompoundCurve)
>         .put("CurvePolygon",wkbCurvePolygon)
>         .put("MultiCurve",wkbMultiCurve)
>         .put("MultiSurface",wkbMultiSurface)
>         .put("PolyhedralSurface",wkbPolyhedralSurface)
>         .build();
> 
>   private static final BiMap<String,Integer> POSTGIS_OGR_DATATYPE_MAP =
>       new ImmutableBiMap.Builder<String, Integer>()
>           .put("integer",OFTInteger)
>           .put("real",OFTReal)
>           .put("varchar",OFTString)
>           .put("bytea",OFTBinary)
>           .put("date",OFTDate)
>           .put("time",OFTTime)
>           .put("timestamp",OFTDateTime)
>           .put("bigint",OFTInteger64)
>           .put("integer[]",OFTIntegerList)
>           .put("real[]",OFTRealList)
>           .put("varchar[]",OFTStringList)
>           .put("bigint[]",OFTInteger64List)
>           .put("text",OFTWideString)

--> OFTWideString is unused. Will be OFTString

>           .put("text[]",OFTWideStringList)

--> same here. OFTStringList

>           .build();
> 
> However, it would obviously be orders of magnitude more
> convenient/future-proofed to simply retrieve these mappings from the
> driver/layer itself since each driver/layer must logically already have such
> a mapping.

That's really an implementation detail. Not sure it is a good idea to expose it,
and that only makes sense for SQL-like drivers. And it is generally not as simple
as a bidirectionnal map. Several postgres types can map to the same OGR field type.

You'll find the postgres->OGR logic in
https://trac.osgeo.org/gdal/browser/trunk/gdal/ogr/ogrsf_frmts/pgdump/ogrpgdumplayer.cpp#L1287

As you can see it also takes into account the field width and precision to decide
if a numeric must be mapped to a OFTReal, OFTInteger or OFTInteger64.

> In addition, is it possible to get the native datatypes that
> would be generated when copying, say a shapefile to postgres without
> actually copying the data itself?

You could just instanciate a target postgres table and add fields from the
source layer field definition, without copying any record. But that would create the table.
Alternatively you could use the PGDump driver for that, that is really close to what the Postgresql
driver does, but that would only write in a file, instead
of modifying a PG db.

$ ogr2ogr -f pgdump /vsistdout/ poly.shp -where "0=1"
SET standard_conforming_strings = OFF;
DROP TABLE IF EXISTS "public"."poly" CASCADE;
DELETE FROM geometry_columns WHERE f_table_name = 'poly' AND f_table_schema = 'public';
BEGIN;
CREATE TABLE "public"."poly" ( "ogc_fid" SERIAL, CONSTRAINT "poly_pk" PRIMARY KEY ("ogc_fid") );
SELECT AddGeometryColumn('public','poly','wkb_geometry',27700,'POLYGON',2);
CREATE INDEX "poly_wkb_geometry_geom_idx" ON "public"."poly" USING GIST ("wkb_geometry");
ALTER TABLE "public"."poly" ADD COLUMN "area" NUMERIC(12,3);
ALTER TABLE "public"."poly" ADD COLUMN "eas_id" NUMERIC(11,0);
ALTER TABLE "public"."poly" ADD COLUMN "prfedea" VARCHAR(16);
COMMIT;

You could probably use gdal.VectorTranslate() for that
http://gdal.org/java/org/gdal/gdal/gdal.html#VectorTranslate-org.gdal.gdal.Dataset-org.gdal.gdal.Dataset-org.gdal.gdal.VectorTranslateOptions-

although I don't think I've tested that the Java bindings for it work correctly

something like

shapefile_ds = gdal.OpenEx("my.shp");
gdal.VectorTranslate("tmp/out.txt", shapefile_ds, new gdal.VectorTranslateOptions(new Vector(Arrays.asList(new String[]{"-of", "PGDump", "-where", "0=1"}))));



Even

-- 
Spatialys - Geospatial professional services
http://www.spatialys.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20170927/ab530260/attachment-0001.html>


More information about the gdal-dev mailing list