V1_0.java [src/java/m/example/gis_geotools] Revision: 6a43cae54bfb109df7bc9a3f6e07e8fe92dc33de Date: Fri Apr 08 12:55:26 MDT 2016
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package m.example.gis_geotools;
//import com.vividsolutions.jts.geom.Geometry;
import csip.ModelDataService;
import static csip.ModelDataService.EXEC_OK;
import csip.ServiceException;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.Path;
import oms3.annotations.Description;
import oms3.annotations.Name;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
//import org.geotools.feature.FeatureCollection;
//import org.geotools.feature.FeatureIterator;
//import org.geotools.geojson.feature.FeatureJSON;
//import org.geotools.geojson.geom.GeometryJSON;
//import org.opengis.feature.Feature;
//import org.opengis.feature.simple.SimpleFeature;
/**
* Basic usage of the GeoTools Geometry and Feature objects.
* NOTE: This example also delves into:
* -- Extended use of the process() return value features....Will soon be deprecated though, so this may not be useful.
* -- SQL statements for MsSQL -vs- PostGIS
* -- Demonstration, in the JSON example input files, of the _proper_ usage of "Geometry", "Feature" and "FeatureCollection" types.
* Notice in the basic_geometry JSON file there is no keyword "Geometry"...This is correct usage. "Geometry" is only specified in
* "Feature" or GeometryCollection, and has been misused, to date, in our service JSON examples .
* The FeatureCollection and Feature types in GeoJSON should be used to their utmost ability, if possible.
* Features that have properties should set those properties in their associated Feature properties section
* not specify them as separate JSONObjects in the input params. Using tools like ArcMap or ArcGIS can, subsequently
* produce the inputs for our services without outside intervention, if we utilize these GeoJSON features correctly.
* Please See: http://geojson.org/geojson-spec.html for further details...
* NOTE: Thus far, to date, our usage of "Feature" and "FeatureCollection" have been invalid GeoJSON in many cases, and this needs to be repaired,
* for instance, every "Feature" MUST have a "properties" section, but most of ours do not...and most of the time, we really mean
* to use "Geometry" not "Feature"....
*
*
* @author Shaun Case
*/
@Name("GIS_GeoTools")
@Description("An example of how to read in geometries or featurecollections using the geotools libraries. Also demonstrates proper GeoJSON, error passing with ModelDataServices and SQL differences between PostGIS and MsSQL")
//@Path("m/gis_geotools/1.0")
public class V1_0 extends ModelDataService {
// Geometry aoa_geometry;
// JSONObject aoa_input_geometry;
//
// @Override
// // NOTE: Changed "Exception" to csip.ServiceException. (It's considered bad form to throw a generic exception in Java)
// // We will check the validity of the param array, if it is present, and return a distinct message identifying what is
// // missing, if necessary, when we throw a csip.ServiceException. This is much better than just throwing the exception
// // with no message at all.
// protected void preProcess() throws csip.ServiceException {
// Map<String, JSONObject> inputParams = getParamMap();
// if (null != inputParams) {
// this.aoa_input_geometry = inputParams.get("aoa_geometry");
// if (null == this.aoa_input_geometry) {
// throw new csip.ServiceException("No 'aoa_geometry' item was found in the JSON input. Please specify an 'aoa_geometry' .");
// }
// } else {
// throw new csip.ServiceException(" No JSON input parameters were found. Please specify some input.");
// }
// }
//
// @Override
// // NOTE: Notice the usage of the ability to return an error message string via the process() routine here, instead of throwing a generic exeption.
// // This feature gives the programmer the ability to return very helpful messages to the client of this service. This makes debugging much
// // simpler when such features are used to their full extent.
// //
// // Also NOTE: This feature will soon be deprecated and using the csip.ServiceException only will be the prefered pathway once the output of the
// // stack traces associated with an exception are moved to a different section of the Metadata of the result rather than the body of the
// // result.
//
// protected String process() throws ServiceException {
// String ret_val = EXEC_OK;
//
// GeometryJSON geoJSON = new GeometryJSON();
// try {
// if (this.aoa_input_geometry.has("features")) {
// FeatureJSON featureJSON = new FeatureJSON();
//
// FeatureCollection inputFeatures = featureJSON.readFeatureCollection(this.aoa_input_geometry.toString());
// FeatureIterator tFeatures = inputFeatures.features();
// int count = 1;
// while (tFeatures.hasNext()) {
// Feature tFeature = tFeatures.next();
// this.aoa_geometry = (Geometry) ((SimpleFeature) tFeature).getAttribute("geometry");
// Logger.getLogger(V1_0.class.getName()).log(Level.INFO, "Feature geometry " + count + " recieved was: {0}", this.aoa_geometry.toText());
// count++;
// // Do something with this particular feature here...OR just grab the first one if only one was specified.
// // This particular code assumes only one was specified, but can easily be altered to send more than one
// // and do something with each....
//
// }
// } else {
// if ( this.aoa_input_geometry.has("type")){ //Try to uncover if this is a "Feature" or a geometry object
// if ( this.aoa_input_geometry.getString("type").equalsIgnoreCase("feature")){
// FeatureJSON featureJSON = new FeatureJSON();
// Feature tFeature = featureJSON.readFeature(this.aoa_input_geometry.toString());
// this.aoa_geometry = (Geometry) ((SimpleFeature) tFeature).getAttribute("geometry");
// // Here we could pull out the Feature's properies as well...
// Logger.getLogger(V1_0.class.getName()).log(Level.INFO, "This Feature''s Id is: {0}", ((SimpleFeature) tFeature).getID());
// Logger.getLogger(V1_0.class.getName()).log(Level.INFO, "This Feature''s name is: {0}", ((SimpleFeature) tFeature).getAttribute("name"));
//
// //NOTE: For some reason, property values that are arrays (as in the example JSON), don't get read, so watch out for this!
// Logger.getLogger(V1_0.class.getName()).log(Level.INFO, "This Feature''s adjustment factor is: {0}", ((SimpleFeature) tFeature).getAttribute("AdjustmentFactor"));
//
// }
// else{ //Try to read the GeoJSON geometry object
// this.aoa_geometry = geoJSON.read(IOUtils.toInputStream(this.aoa_input_geometry.toString()));
// }
// }
// else{
//
// }
// }
//
// // TODO: Add your code here to do something with the geometry(ies) you read in.
// // For instance: See code lines below: (NOTE: The .toText() funciton of "Geometry" returns WKT..)
// // Log the WKT of the input.
// Logger.getLogger(V1_0.class.getName()).log(Level.INFO, "Last aoa_geometry value recieved was: {0}", this.aoa_geometry.toText());
//
// String Query;
// // PostGIS specific SQL statement below to calculate area in acres.
// Query = "SELECT st_area(st_transform(ST_PolygonFromText('" + this.aoa_geometry.toText() + "', 4326),3541))/43560 as areaInAcres; ";
//
// // MsSQL specific SQL statement below to calculate area in acres. (NOTE: Assumes point rotation is openGIS compliant, i.e. non-ESRI Shapefile)
// Query = "SELECT geography::STGeomFromText('" + this.aoa_geometry.toText() + "', 4326).MakeValid().STArea() / 4046.86 as areaInAcres; ";
//
// // MsSQL specific SQL statement below to calculate area in acres. (NOTE: Assumes point rotation is non-openGIS compliant, i.e. ESRI Shapefile)
// Query = "SELECT geography::STGeomFromText('" + this.aoa_geometry.toText() + "', 4326).ReorientObject().MakeValid().STArea() / 4046.86 as areaInAcres; ";
//
// } catch (IOException ex) {
// Logger.getLogger(V1_0.class.getName()).log(Level.SEVERE, "Cannot parse the input GeoJSON into valid GIS entities: ", ex);
// // This will return a useable error message to the user via the process() return value, rather than a exception stacktrace, with no explanations.
// ret_val = "Cannot parse the input GeoJSON into valid GIS entities: " + ex.getMessage();
// // Or
// //throw new csip.ServiceException( ex );
// } catch (JSONException ex) {
// Logger.getLogger(V1_0.class.getName()).log(Level.SEVERE, "Cannot parse the aoa_geometry geometry type. Please check your syntax. ", ex);
// ret_val = "Cannot parse the aoa_geometry geometry type. Please check your syntax. " + ex.getMessage();
// // Or
// //throw new csip.ServiceException( ex );
// }
//
// return ret_val;
// }
}