1

i am pretty new in Java Programming so i am thankfull for any help. I am currently trying to get the Features of a WFS Datastore to be accessed in the another class of the project - for further retransforming the projection and displaying these features with processing.

with return wfsDSF i somehow can't access the features (lon, lat, date, time, rate..)

Printing the features in console already works for me.

here the code (except for url and featuresource):

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.wfs.WFSDataStore;
import org.geotools.data.wfs.WFSDataStoreFactory;
import org.opengis.feature.Feature;


public class WFSConnector {

public static WFSDataStoreFactory wfsDSF () throws SQLException {

    // define the getCapabilities request
    String wfsGetCapabilitiesURL = "URL";

    // create WFSDataStoreFactory object
    WFSDataStoreFactory wfsDSF = new WFSDataStoreFactory();

    // create HashMap and fill it with connection parameters
    HashMap connectionParameters = new HashMap();
    connectionParameters.put(WFSDataStoreFactory.URL.key, wfsGetCapabilitiesURL);
    connectionParameters.put(WFSDataStoreFactory.TIMEOUT.key, 20000);

    try {
        WFSDataStore wfsDS = wfsDSF.createDataStore(connectionParameters);          
        SimpleFeatureSource sfSource = wfsDS.getFeatureSource("SELECTED-FEATURE");
        SimpleFeatureCollection sfCollection = sfSource.getFeatures();
        SimpleFeatureIterator sfIterator = sfCollection.features();          

       // check if the FeatureReader object holds another
       while(sfIterator.hasNext() == true)
       {
            //iterate through the "rows" of the WFS response
            Feature currentFeature = sfIterator.next();

            String coordinates = currentFeature.getProperty("the_geom").getValue().toString();
            String fphenomenon = currentFeature.getProperty("phenomenon").getValue().toString();
            String ftriptime = currentFeature.getProperty("tripTime").getValue().toString();
            String fheartrate = currentFeature.getProperty("heartrate").getValue().toString();

            //get rid of the name "point" and the brackets of the geometry string
            int x = coordinates.lastIndexOf('(');
            int y = coordinates.lastIndexOf(')');
            String coord = coordinates.substring(x+1, y);                

            //split the coordinates into 2 parts
            String[] splitcoordinates = coord.split(" ");
            String lon = splitcoordinates[0];
            String lat = splitcoordinates[1];

            //split phenomenon into date and time                                
            String date = fphenomenon.substring(0,10); 
            String time = fphenomenon.substring(11,19);  

            {
                System.out.println(lon  + " : " + lat + " : " + date + " : " + time + " : " + ftriptime + " : " + fheartrate);
            }
       }          
    } 
    catch (IOException e2) {
        e2.printStackTrace();
        }

    return wfsDSF;  

} // main
} // class
Chris S.
  • 21
  • 2

1 Answers1

0

You are heading in the right direction, but there are some easier methods to help with what you are trying to do. Usually, I would return the FeatureCollection to my main program to carry out the processing there.

So something like:

private SimpleFeatureCollection getFeatureCollection(String typeName) throws IOException {
   return dataStore.getFeatureSource(typeName).getFeatures();
}

String typeName = "topp:states";
SimpleFeatureCollection features = me.getFeatureCollection(typeName);
try (SimpleFeatureIterator itr = features.features()) {
  while (itr.hasNext()) {
    SimpleFeature f = itr.next();
    //[.......]
  }
}

is a common pattern. Note, unless forced to always use SimpleFeatures rather than generic ones. Then rather than complex string manipulation the attributes can be accessed as Java Objects with suitable casts.

    SimpleFeature f = itr.next();
    Geometry geom = (Geometry) f.getDefaultGeometry();
    double lat = geom.getCentroid().getY();
    double lon = geom.getCentroid().getX();
    String name = (String) f.getAttribute("STATE_NAME");
    String abbr = (String) f.getAttribute("STATE_ABBR");
    double people = (double) f.getAttribute("PERSONS");
    System.out.println(name + "\t(" + abbr + ")\t" + people + "\t(" + lat + "," + lon + ")");

Obviously, you are free to do whatever processing you want in this loop. For the geometry I took the centroid since I knew I had a polygon, if you have points then just call .getX() & .getY() on the point directly.

Here is the whole program:

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.wfs.WFSDataStoreFactory;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

public class GetWFSAttributes {
  DataStore dataStore = null;

  public static void main(String[] args) throws IOException {
    String getCapabilities = "http://localhost:8080/geoserver/ows?service=wfs&version=1.1.0&request=GetCapabilities";
    GetWFSAttributes me = new GetWFSAttributes(getCapabilities);
    String[] names = me.getTypeNames();
    for (String name : names) {
      SimpleFeatureType schema = me.getSchema(name);
      System.out.println(name + ":" + schema);
    }

    String typeName = "topp:states";
    SimpleFeatureCollection features = me.getFeatureCollection(typeName);
    try (SimpleFeatureIterator itr = features.features()) {
      while (itr.hasNext()) {
        SimpleFeature f = itr.next();
        Geometry geom = (Geometry) f.getDefaultGeometry();
        double lat = geom.getCentroid().getY();
        double lon = geom.getCentroid().getX();
        String name = (String) f.getAttribute("STATE_NAME");
        String abbr = (String) f.getAttribute("STATE_ABBR");
        double people = (double) f.getAttribute("PERSONS");
        System.out.println(name + "\t(" + abbr + ")\t" + people + "\t(" + lat + "," + lon + ")");
      }
    }
  }

  private SimpleFeatureCollection getFeatureCollection(String typeName) throws IOException {
    return dataStore.getFeatureSource(typeName).getFeatures();
  }

  private String[] getTypeNames() throws IOException {
    return dataStore.getTypeNames();
  }

  private SimpleFeatureType getSchema(String name) throws IOException {
    return dataStore.getSchema(name);
  }

  public GetWFSAttributes(String capabilities) {
    aquireDataStoreWFS(capabilities);
  }

  public void aquireDataStoreWFS(String capabilities) {
    if (dataStore == null) {
      try {
        Map<String, Serializable> connectionParameters = new HashMap<>();
        connectionParameters.put(WFSDataStoreFactory.URL.key, capabilities);
        dataStore = DataStoreFinder.getDataStore(connectionParameters);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}
Ian Turton
  • 10,018
  • 1
  • 28
  • 47