1

I have the following code, referenced from my previous post: https://stackoverflow.com/questions/52554587/add-new-column-attribute-to-the-shapefile-and-save-it-to-database-using-geotools. So what I am trying to do here is basically set the SRS value to EPSG:4326 which is intially 0 (ST_SRID(geom)). In postgis its simple to update which is like this:

UPDATE spatial_table
-- update the srid
SET geom  = ST_SetSRID(geom, 4326)
-- only alters rows that don't already have an srid assigned
WHERE ST_SRID(geom) = 0;

But since I am using geotools to store into the postgis, I want to know if there is any way i could set the SRS while saving it into the database.

I tried the following but didn't work:

FileDataStore ds = FileDataStoreFinder.getDataStore(new File(FilePath));
        SimpleFeatureType schema = ds.getSchema();
        System.out.println("Schema getName :"+ schema.getName());
        System.out.println("Schema getTypeName :"+ schema.getTypeName());
        // create new schema
        SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
        builder.setName(schema.getTypeName().replaceAll("%20", "_").toLowerCase());
       // builder.setCRS( DefaultGeographicCRS.WGS84); //didn't work
       // builder.setCRS(CRS.decode("EPSG:4326",true)); //didn't work
        builder.setSuperType((SimpleFeatureType) schema.getSuper());
        builder.addAll(schema.getAttributeDescriptors());

         System.out.println("After replacement :"+ schema.getName().toString().replaceAll("%20", "_").replaceAll(" ", "_"));
        // add new attribute(s)
        //builder.add("shapeID", String.class)
        // build new schema
        SimpleFeatureType nSchema = builder.buildFeatureType();
        System.out.println("Shapefile table info : " + nSchema);

        //System.out.println("Adding column attr to shpfile");
        // loop through features adding new attribute
        List<SimpleFeature> features = new ArrayList<>();
        try (SimpleFeatureIterator itr = ds.getFeatureSource().getFeatures().features()) {
            while (itr.hasNext()) {
                SimpleFeature f = itr.next();
                SimpleFeature f2 = DataUtilities.reType(nSchema, f);

               // f2.setAttribute("shapeID", ID);
                //System.out.println(f2);
                features.add(f2);
            }
        }
        Properties params = new Properties();
        // Configure the PostGIS database here
        params.put("user", "test");
        params.put("passwd", "postgres");
        params.put("port", "5432");
        params.put("host", "127.0.0.1");
        params.put("database", "testdb");
        params.put("dbtype", "postgis");
       // params.put(PostgisNGDataStoreFactory.LOOSEBBOX, true );

        DataStore dataStore = DataStoreFinder.getDataStore(params);
    try{
    if (dataStore == null) {
        System.out.println("Failed to connect to PostGIS");
        System.exit(1);
    }
    String tableName = nSchema.getTypeName();
    user.settableName(tableName);
    boolean exists = false;
    String[] names = dataStore.getTypeNames();
    for (String name : names) {
        if (name.equalsIgnoreCase(tableName)) {
            exists = true;
            break;
        }
    }
    if (!exists) {
        dataStore.createSchema(nSchema);
    }
    SimpleFeatureSource source = dataStore.getFeatureSource(tableName);
    if (source instanceof SimpleFeatureStore) {
        SimpleFeatureStore store = (SimpleFeatureStore) source;
        store.addFeatures(DataUtilities.collection(features));
        System.out.println("Successfully created a database");
        flag = true;
    } else {
        System.err.println("Unable to connect to database");
        flag = false;
    }
   }
    finally{
            dataStore.dispose();
            }

      return flag;
  }

EDIT: 1. builder.setCRS( DefaultGeographicCRS.WGS84) // I am sure whether this is the way I need to set, but just a try based on the example code.

  1. builder.setCRS(CRS.decode("EPSG:4326",true)); // CRS.decode() the method is no longer available. The import dependency is as follows: org.geotools.data.Parameter.CRS;

I am using geotools dependency as follows:

   <artifactId>GeoDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
   <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <geotools.version>20-SNAPSHOT</geotools.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>it.geosolutions</groupId>
            <artifactId>geoserver-manager</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${geotools.version}</version>
        </dependency>
  • please say why the 2 commented out lines didn't work. Also we need to see the code where you create the postgis table. – Ian Turton Nov 23 '18 at 10:52
  • @IanTurton updated the question based on ur inputs... – GeoFresher Nov 23 '18 at 11:04
3

This only occurs if you are processing shapefiles with no .prj file, try to avoid doing this as they are just collections of random numbers. Always prefer going back and fixing the process or person generating the dataset.

Any way if you are stuck dealing with poor quality data then you can fix it by changing the GeometryDescriptor in the new schema to reference the required CRS.

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
AttributeTypeBuilder attributeBuilder = new AttributeTypeBuilder();
builder.setName(schema.getName());
builder.setSuperType((SimpleFeatureType) schema.getSuper());

List<AttributeDescriptor> attributes = schema.getAttributeDescriptors();

for (AttributeDescriptor attrib : attributes) {
  AttributeType type = attrib.getType();
  if (type instanceof GeometryType) {
    if (schema.getCoordinateReferenceSystem() == null) {
      // need to set the crs
      DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84;
      builder.setCRS(crs);
      GeometryDescriptor g = schema.getGeometryDescriptor();
      attributeBuilder.init(g);
      attributeBuilder.setCRS(crs);
      GeometryDescriptor att = (GeometryDescriptor) attributeBuilder.buildDescriptor(g.getLocalName());
      builder.add(att);
      builder.setDefaultGeometry(att.getLocalName());
    } else {
      builder.add(attrib);
      builder.setDefaultGeometry(attrib.getLocalName());
    }
  } else {
    builder.add(attrib);
  }
}
  • The GeometryDescriptor info was really helpful. Thanks Ian :) – GeoFresher Nov 26 '18 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.