git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-analysis/EcologicalEngineGeoSpatialExtension@75000 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
c82d3636b1
commit
c5b12ad5bf
|
@ -1,8 +1,7 @@
|
|||
package org.gcube.dataanalysis.geo.retrieval;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -12,10 +11,17 @@ import org.gcube.dataanalysis.ecoengine.signals.SignalProcessing;
|
|||
import org.gcube.dataanalysis.ecoengine.utils.Tuple;
|
||||
import org.gcube.dataanalysis.geo.meta.features.FeaturesManager;
|
||||
import org.gcube.dataanalysis.geo.utils.EnvDataExplorer;
|
||||
import org.gcube.dataanalysis.geo.utils.FeaturedPolygon;
|
||||
import org.gcube.dataanalysis.geo.utils.ThreddsDataExplorer;
|
||||
import org.opengis.metadata.Metadata;
|
||||
import org.opengis.metadata.identification.Identification;
|
||||
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.PrecisionModel;
|
||||
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
|
||||
|
||||
public class GeoIntersector {
|
||||
|
||||
private FeaturesManager featurer;
|
||||
|
@ -88,18 +94,30 @@ public class GeoIntersector {
|
|||
}
|
||||
*/
|
||||
} else {
|
||||
//TODO: adjust WFS take
|
||||
AnalysisLogger.getLogger().debug("found a Geo Layer with title " + layerTitle + " and layer name " + layer);
|
||||
/*
|
||||
for (Tuple<Double> triplet : triplets) {
|
||||
double x = triplet.getElements().get(0);
|
||||
double y = triplet.getElements().get(1);
|
||||
AnalysisLogger.getLogger().debug("Taking point: (" + x + "," + y + ")");
|
||||
LinkedHashMap<String, Double> features = new LinkedHashMap<String, Double>();
|
||||
features = getFeaturesFromWFS(featurer.getWFSLink(meta), layer, x, y);
|
||||
featuresSets.add(features);
|
||||
}
|
||||
*/
|
||||
// AnalysisLogger.getLogger().debug("Taking point: (" + x + "," + y + ")");
|
||||
List<FeaturedPolygon> featuresInTime = new ArrayList<FeaturedPolygon>();
|
||||
AnalysisLogger.getLogger().debug("taking WFS features");
|
||||
featuresInTime = getFeaturesFromWFS(featurer.getGeoserverLink(meta), layer, xL,yL, xR, yR);
|
||||
AnalysisLogger.getLogger().debug("Intersecting "+triplets.size()+" vs "+featuresInTime.size() +" elements");
|
||||
for (Tuple<Double> triplet:triplets){
|
||||
GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4326);
|
||||
CoordinateArraySequence pcoords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(triplet.getElements().get(0),triplet.getElements().get(1)),});
|
||||
Point po = new Point(pcoords, factory);
|
||||
boolean found = false;
|
||||
for (FeaturedPolygon poly:featuresInTime){
|
||||
|
||||
if (poly.p.covers(po)){
|
||||
// System.out.println(po+" intersected by "+poly.p);
|
||||
features.add(poly.value);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (!found)
|
||||
features.add(Double.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
|
@ -119,14 +137,21 @@ public class GeoIntersector {
|
|||
return ThreddsDataExplorer.retrieveDataFromNetCDF(opendapURL, layer, x, y, z);
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, Double> getFeaturesFromWFS(String wfsUrl, String layer, double x, double y) {
|
||||
if (wfsUrl == null)
|
||||
private LinkedHashMap<String, Double> getFeaturesFromWFS(String geoserverUrl, String layer, double x, double y) {
|
||||
if (geoserverUrl == null)
|
||||
return null;
|
||||
|
||||
return EnvDataExplorer.getFeatures(wfsUrl, layer, x, y);
|
||||
return EnvDataExplorer.getFeatures(geoserverUrl, layer, x, y);
|
||||
}
|
||||
|
||||
public double[][] takeLastTimeChunk(String layerTitle, double x1, double x2, double y1, double y2, double z, double xResolution, double yResolution) throws Exception {
|
||||
private List<FeaturedPolygon> getFeaturesFromWFS(String geoserverUrl, String layer, double xL,double yL,double xR, double yR) {
|
||||
if (geoserverUrl == null)
|
||||
return null;
|
||||
|
||||
return EnvDataExplorer.getFeatures(geoserverUrl, layer, xL,yL,xR, yR);
|
||||
}
|
||||
|
||||
public double[][] takeTimeSlice(String layerTitle, int timeInstant, double x1, double x2, double y1, double y2, double z, double xResolution, double yResolution) throws Exception {
|
||||
AnalysisLogger.getLogger().debug("Bounding box: (" + x1 + "," + x2 + ";" + y1 + "," + y2 + ")");
|
||||
if ((x2 < x1) || (y2 < y1)) {
|
||||
AnalysisLogger.getLogger().debug("ERROR: BAD BOUNDING BOX!!!");
|
||||
|
@ -152,17 +177,17 @@ public class GeoIntersector {
|
|||
}
|
||||
|
||||
AnalysisLogger.getLogger().debug("Taking " + ysteps + " values per "+xsteps+"="+(ysteps*xsteps)+ "...");
|
||||
List<Double> time = getFeaturesInTimeInstant(layerTitle, 0, tuples, x1, x2, y1,y2);
|
||||
AnalysisLogger.getLogger().debug("Taken " + time.size() + " values");
|
||||
List<Double> timeValues = getFeaturesInTimeInstant(layerTitle, timeInstant, tuples, x1, x2, y1,y2);
|
||||
AnalysisLogger.getLogger().debug("Taken " + timeValues.size() + " values");
|
||||
|
||||
// build back the values matrix
|
||||
int k = 0;
|
||||
int g = 0;
|
||||
int ntriplets = time.size();
|
||||
int ntriplets = timeValues.size();
|
||||
//cycle on all the triplets to recontruct the matrix
|
||||
for (int t = 0; t < ntriplets; t++) {
|
||||
//take the corresponding (time,value) pair
|
||||
Double value = time.get(t);
|
||||
Double value = timeValues.get(t);
|
||||
//if there is value, then set it, otherwise set NaN
|
||||
//the layer is undefined in that point and a value must be generated
|
||||
//assign a value to the matrix
|
||||
|
|
|
@ -14,9 +14,9 @@ public class TestChunkization {
|
|||
long t0 = System.currentTimeMillis();
|
||||
AnalysisLogger.setLogger(cfg+AlgorithmConfiguration.defaultLoggerFile);
|
||||
GeoIntersector intersector = new GeoIntersector(null, cfg);
|
||||
// intersector.takeLastTimeChunk(layertitle, -180, 180, -10, 10, 0, 1, 1);
|
||||
intersector.takeLastTimeChunk(layertitle, -10, 10, -10, 10, 0,1, 1);
|
||||
// intersector.takeLastTimeChunk(layertitle, -180, 180, -90, 90, 0, 1, 1);
|
||||
// intersector.takeTimeSlice(layertitle, 0, -180, 180, -10, 10, 0, 1, 1);
|
||||
// intersector.takeTimeSlice(layertitle, 0, -10, 10, -10, 10, 0,1, 1);
|
||||
intersector.takeTimeSlice(layertitle, 0, -180, 180, -90, 90, 0, 0.5, 0.5);
|
||||
System.out.println("ELAPSED TIME: "+(System.currentTimeMillis()-t0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.gcube.dataanalysis.geo.test;
|
||||
|
||||
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
|
||||
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
|
||||
import org.gcube.dataanalysis.geo.retrieval.GeoIntersector;
|
||||
|
||||
public class TestChunkizationLayer {
|
||||
|
||||
static String cfg = "./cfg/";
|
||||
public static void main(String[] args) throws Exception{
|
||||
String layertitle = "MyDistributionMap";
|
||||
// String layertitle = "Mass Concentration of Chlorophyll in Sea Water in [03-30-13 01:00] (3D) {Mercator Ocean BIOMER1V1R1: Data extracted from dataset http://atoll-mercator.vlandata.cls.fr:44080/thredds/dodsC/global-analysis-bio-001-008-a}";
|
||||
// String layertitle = "Objectively Analyzed Climatology in [07-01-01 01:00] (3D) {World Ocean Atlas 09: Sea Water Temperature - annual: dods://thredds.research-infrastructures.eu/thredds/dodsC/public/netcdf/temperature_annual_1deg_ENVIRONMENT_OCEANS_.nc}";
|
||||
long t0 = System.currentTimeMillis();
|
||||
AnalysisLogger.setLogger(cfg+AlgorithmConfiguration.defaultLoggerFile);
|
||||
GeoIntersector intersector = new GeoIntersector(null, cfg);
|
||||
// intersector.takeTimeSlice(layertitle, 0, -10, 10, -10, 10, 0,1, 1);
|
||||
intersector.takeTimeSlice(layertitle, 0, -180, 180, -90, 90, 0, 0.5, 0.5);
|
||||
System.out.println("ELAPSED TIME: "+(System.currentTimeMillis()-t0));
|
||||
}
|
||||
}
|
|
@ -1,18 +1,48 @@
|
|||
package org.gcube.dataanalysis.geo.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.contentmanagement.graphtools.utils.HttpRequest;
|
||||
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
|
||||
import org.gcube.dataanalysis.geo.meta.OGCFormatter;
|
||||
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.LinearRing;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
import com.vividsolutions.jts.geom.PrecisionModel;
|
||||
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
|
||||
|
||||
public class EnvDataExplorer {
|
||||
|
||||
private static String callWFS(String geoServer, String layer, double x, double y) {
|
||||
|
||||
float tolerance = 0.25f;
|
||||
String wfsURL = OGCFormatter.getWfsUrl(geoServer, layer, OGCFormatter.pointToBoundingBox(x, y, tolerance), 1, "json");
|
||||
String wfsURL = OGCFormatter.getWfsUrl(geoServer, layer, OGCFormatter.pointToBoundingBox(x, y, tolerance), 1, "json");
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> Requesting URL: " + wfsURL);
|
||||
String returned = null;
|
||||
try {
|
||||
returned = HttpRequest.sendGetRequest(wfsURL, null);
|
||||
} catch (Exception e) {
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> ERROR " + e.getLocalizedMessage());
|
||||
}
|
||||
if (returned != null)
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> Found Intersection: " + returned);
|
||||
else
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> Found Nothing!");
|
||||
|
||||
return returned;
|
||||
}
|
||||
|
||||
private static String callWFS(String geoServer, String layer, double xL, double yL, double xR, double yR) {
|
||||
|
||||
// String wfsURL = OGCFormatter.getWfsUrl(geoServer, layer, OGCFormatter.buildBoundingBox(xL, yL, xR, yR), 0, "json");
|
||||
// there is a bug in WFS in the retrieval according to a bounding box: y must be in the range -180;180. then I preferred to take all the features
|
||||
String wfsURL = OGCFormatter.getWfsUrl(geoServer, layer, null, 0, "json");
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> Requesting URL: " + wfsURL);
|
||||
String returned = null;
|
||||
try {
|
||||
|
@ -30,11 +60,12 @@ public class EnvDataExplorer {
|
|||
|
||||
public static LinkedHashMap<String, Double> getFeatures(String geoserver, String layer, double x, double y) {
|
||||
try {
|
||||
AnalysisLogger.getLogger().debug("Calling WFS towards Geoserver:" + geoserver + " and layer:" + layer);
|
||||
String jsonString = callWFS(geoserver, layer, x, y);
|
||||
LinkedHashMap<String, Object> map = JsonMapper.parse(jsonString);
|
||||
LinkedHashMap<String, String> mapout = (LinkedHashMap<String, String>) ((HashMap<String, Object>) map.get("features")).get("properties");
|
||||
LinkedHashMap<String, Double> values = new LinkedHashMap<String, Double>();
|
||||
for (String key:mapout.keySet()){
|
||||
LinkedHashMap<String, Double> values = new LinkedHashMap<String, Double>();
|
||||
for (String key : mapout.keySet()) {
|
||||
values.put(key, Double.parseDouble(mapout.get(key)));
|
||||
}
|
||||
return values;
|
||||
|
@ -43,4 +74,144 @@ public class EnvDataExplorer {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<FeaturedPolygon> getFeatures(String geoserver, String layer, double xL, double yL, double xR, double yR) {
|
||||
try {
|
||||
AnalysisLogger.getLogger().debug("Calling WFS towards Geoserver:" + geoserver + " and layer:" + layer);
|
||||
String jsonString = callWFS(geoserver, layer, xL, yL, xR, yR);
|
||||
// System.out.println("JSON:"+jsonString);
|
||||
LinkedHashMap<String, Object> map = JsonMapper.parse(jsonString);
|
||||
List<FeaturedPolygon> fpolygons = new ArrayList<FeaturedPolygon>();
|
||||
FeaturedPolygon poly = null;
|
||||
for (String key : map.keySet()) {
|
||||
if (key.contains("features")) {
|
||||
HashMap<String, Object> propertiesMap = (HashMap<String, Object>) map.get(key);
|
||||
|
||||
//cycle on all the properties
|
||||
for (String properties : propertiesMap.keySet()) {
|
||||
if (properties.contains("properties")) {
|
||||
if (poly==null)
|
||||
poly=new FeaturedPolygon();
|
||||
|
||||
LinkedHashMap<String, String> props = (LinkedHashMap<String, String>) propertiesMap.get(properties);
|
||||
//fill the properties of the fpolygon
|
||||
for (String keyprop : props.keySet()) {
|
||||
try {
|
||||
//fulfill the FeaturedPolygon
|
||||
String value = props.get(keyprop);
|
||||
try{
|
||||
String lowcaseprop = keyprop.toLowerCase();
|
||||
if ((poly.value==null) &&
|
||||
!lowcaseprop.startsWith("id")&&
|
||||
!lowcaseprop.endsWith("id"))
|
||||
poly.setValue(Double.parseDouble(value));
|
||||
else
|
||||
poly.addFeature(keyprop, value);
|
||||
}catch (Exception e2){
|
||||
poly.addFeature(keyprop, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (properties.contains("geometry") && !properties.contains("geometry_")) {
|
||||
|
||||
if (poly==null)
|
||||
poly=new FeaturedPolygon();
|
||||
else if (poly.p!=null){
|
||||
if (poly.value==null)
|
||||
poly.value=Double.NaN;
|
||||
fpolygons.add(poly);
|
||||
poly=new FeaturedPolygon();
|
||||
}
|
||||
|
||||
LinkedHashMap<String, String> props = (LinkedHashMap<String, String>) propertiesMap.get(properties);
|
||||
List<double[]> coords = WFS2Coordinates(props.toString());
|
||||
GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4326);
|
||||
Polygon p = null;
|
||||
if (coords != null) {
|
||||
Coordinate[] coordarray = new Coordinate[coords.size()];
|
||||
int i=0;
|
||||
for (double[] pair:coords){
|
||||
coordarray[i] = new Coordinate(pair[0],pair[1]);
|
||||
i++;
|
||||
}
|
||||
CoordinateArraySequence coordseq = new CoordinateArraySequence(coordarray);
|
||||
LinearRing ring = new LinearRing(coordseq, factory);
|
||||
p = new Polygon(ring, new LinearRing[] {}, factory);
|
||||
}
|
||||
poly.setPolygon(p);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}// end for on all the wfs
|
||||
|
||||
if (poly!=null){
|
||||
if (poly.value==null)
|
||||
poly.value=Double.NaN;
|
||||
fpolygons.add(poly);
|
||||
}
|
||||
return fpolygons;
|
||||
} catch (Exception e) {
|
||||
AnalysisLogger.getLogger().debug("EnvDataExplorer-> Error in getting properties");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<double[]> WFS2Coordinates(String wfsgeometry) {
|
||||
|
||||
// geometry935133b1-ba3c-493d-8e18-6fb496ced995={type=MultiPolygon, coordinates={966a275c-23aa-4a43-a943-7e1c7eaf5d65=[[[1.5,125.00000000000011],[1.5,124.5],[2.000000000000057,124.5],[2.000000000000057,125.00000000000011],[1.5,125.00000000000011]]]}},
|
||||
String[] coordinatePairs = null;
|
||||
List<double[]> dpairs = new ArrayList<double[]>();
|
||||
if (wfsgeometry.toLowerCase().contains("multipolygon")) {
|
||||
String coordString = "coordinates=";
|
||||
String coordinates = wfsgeometry.substring(wfsgeometry.indexOf(coordString) + coordString.length());
|
||||
coordinates = coordinates.substring(coordinates.indexOf("=")+1);
|
||||
coordinatePairs = coordinates.split("\\],\\[");
|
||||
for (String coord : coordinatePairs) {
|
||||
coord = coord.replaceAll("(\\[|\\]|\\}|\\{|)", "");
|
||||
String[] coordpair = coord.split(",");
|
||||
double[] dd = new double[2];
|
||||
//invert the coordinates as the final must be are long,lat
|
||||
dd[1] = Double.parseDouble(coordpair[0]);
|
||||
dd[0] = Double.parseDouble(coordpair[1]);
|
||||
dpairs.add(dd);
|
||||
}
|
||||
}
|
||||
return dpairs;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String geom = "{type=MultiPolygon, coordinates={cce4daf3-966e-4b5f-adea-f88ea2b93d03=[[[-16,-146.49999999999997],[-16,-146.99999999999994],[-15.5,-146.99999999999994],[-15.5,-146.49999999999997],[-16,-146.49999999999997]]]}}";
|
||||
List<double[]> coords = WFS2Coordinates(geom);
|
||||
|
||||
GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4326);
|
||||
// GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 0);
|
||||
/*
|
||||
* CoordinateArraySequence coords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(12.0, 34.23), new Coordinate(12.000, 54.555), new Coordinate(7, 8), new Coordinate(12.0, 34.23) }); LinearRing ring = new LinearRing(coords, factory); Polygon p = new Polygon(ring, null, factory); CoordinateArraySequence pcoords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(12.0, 34.23),});
|
||||
*/
|
||||
// CoordinateArraySequence coords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(1.5, 125.00000000000011), new Coordinate(1.5, 124.5), new Coordinate(2.000000000000057, 124.5), new Coordinate(2.000000000000057, 125.00000000000011), new Coordinate(1.5, 125.00000000000011) });
|
||||
|
||||
if (coords != null) {
|
||||
Coordinate[] coordarray = new Coordinate[coords.size()];
|
||||
int i=0;
|
||||
for (double[] pair:coords){
|
||||
coordarray[i] = new Coordinate(pair[0],pair[1]);
|
||||
i++;
|
||||
}
|
||||
CoordinateArraySequence coordseq = new CoordinateArraySequence(coordarray);
|
||||
LinearRing ring = new LinearRing(coordseq, factory);
|
||||
Polygon p = new Polygon(ring, new LinearRing[] {}, factory);
|
||||
// CoordinateArraySequence pcoords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(-16,-146.49999999999997), });
|
||||
CoordinateArraySequence pcoords = new CoordinateArraySequence(new Coordinate[] { new Coordinate(-150,-16), });
|
||||
Point po = new Point(pcoords, factory);
|
||||
// po = p.getCentroid();
|
||||
System.out.println("contains: " + p.contains(po)+" boundary: "+p.covers(po));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.gcube.dataanalysis.geo.utils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
public class FeaturedPolygon {
|
||||
public Polygon p;
|
||||
public LinkedHashMap<String, String> features;
|
||||
public Double value;
|
||||
public FeaturedPolygon(){
|
||||
|
||||
}
|
||||
|
||||
public void setPolygon(Polygon p){
|
||||
this.p=p;
|
||||
}
|
||||
|
||||
public void setValue(Double v){
|
||||
this.value=v;
|
||||
}
|
||||
|
||||
public void addFeature(String key,String value){
|
||||
if (features==null)
|
||||
features = new LinkedHashMap<String, String>();
|
||||
features.put(key,value);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.util.Iterator;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -32,6 +33,9 @@ public class JsonMapper {
|
|||
parseMap(map, (JsonObject) element);
|
||||
}
|
||||
}
|
||||
else{
|
||||
map.put(UUID.randomUUID().toString(), element.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +51,10 @@ public class JsonMapper {
|
|||
Map.Entry<String, JsonElement> entry = iterator.next();
|
||||
String key = entry.getKey();
|
||||
JsonElement value = entry.getValue();
|
||||
if (map.get(key)!=null){
|
||||
key+=UUID.randomUUID();
|
||||
}
|
||||
|
||||
if (!value.isJsonPrimitive()) {
|
||||
map.put(key, parse(value.toString()));
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue