You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
geoportal-data-viewer-app/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/gis/FeatureParser.java

189 lines
6.4 KiB
Java

/**
*
*/
package org.gcube.portlets.user.geoportaldataviewer.server.gis;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.gcube.application.geoportalcommon.shared.gis.BoundsMap;
import org.gcube.application.geoportalcommon.util.URLParserUtil;
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants;
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem;
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.Coordinate;
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureGeometry;
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureRow;
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.PointsPath;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class FeatureParser.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Nov 13, 2020
*/
public class FeatureParser {
private static Logger LOG = LoggerFactory.getLogger(FeatureParser.class);
/**
* Gets the WFS features.
*
* @param layerItem the layer item
* @param mapSrsName the map srs name
* @param selectBBOX the select BBOX
* @param maxWFSFeature the max WFS feature
* @return the WFS features
*/
public static List<FeatureRow> getWFSFeatures(LayerItem layerItem, String mapSrsName, BoundsMap selectBBOX, int maxWFSFeature) {
if(maxWFSFeature<0) {
maxWFSFeature = GeoportalDataViewerConstants.MAX_WFS_FEATURES;
}
return getWFSFeatureProperties(layerItem, mapSrsName, selectBBOX, maxWFSFeature);
}
/**
* Gets the WFS feature properties.
*
* @param layerItem the layer item
* @param mapSrsName the map srs name
* @param selectBBOX the select BBOX
* @param maxWFSFeature the max WFS feature
* @return the WFS feature properties
*/
@SuppressWarnings("unchecked")
private static List<FeatureRow> getWFSFeatureProperties(LayerItem layerItem, String mapSrsName, BoundsMap selectBBOX, int maxWFSFeature) {
LOG.info("getWFSFeatureProperties for layerItem: "+layerItem.getName() +" in the "+selectBBOX +" and maxWFSFeature: "+maxWFSFeature);
InputStream is = null;
List<FeatureRow> listFeaturesRow = new ArrayList<FeatureRow>();
try {
String url = GisMakers.buildWFSFeatureQuery(layerItem, mapSrsName, selectBBOX, maxWFSFeature, GisMakers.JSON);
String cqlFilterValue = URLParserUtil.extractValueOfParameterFromURL(GisMakers.CQL_FILTER_PARAMETER, url);
LOG.info("Found CQL filter value into query string: "+cqlFilterValue);
if(cqlFilterValue!=null) {
String notEncodedCQLFilter = String.format("%s=%s",GisMakers.CQL_FILTER_PARAMETER,cqlFilterValue);
//log.info("Found CQL filter: "+notEncodedCQLFilter);
String toEncodeCQLFilter = String.format("%s=%s",GisMakers.CQL_FILTER_PARAMETER,URLEncoder.encode(cqlFilterValue,"UTF-8"));
LOG.debug("Encoded CQL filter: "+toEncodeCQLFilter);
url = url.replace(notEncodedCQLFilter, toEncodeCQLFilter);
}
LOG.info("Built WFS URL: "+url);
is = new URL(url).openStream();
String jsonTxt = IOUtils.toString(is);
if(jsonTxt==null || jsonTxt.isEmpty()){
jsonTxt = "{\"type\":\"FeatureCollection\",\"features\":[]}";
}
// get json object
JSONObject json = new JSONObject(jsonTxt);
// iterate features
JSONArray features = json.getJSONArray("features");
if(features.length()==0) {
LOG.info("No features detected in the response, returning empty list");
return listFeaturesRow;
}
String featureCRSName = "";
try {
JSONObject crs = json.getJSONObject("crs");
JSONObject crsProp = crs.getJSONObject("properties");
featureCRSName = crsProp.getString("name");
LOG.info("Crs name found: "+featureCRSName);
}catch (Exception e) {
LOG.warn("Unable to read the field 'crs'");
}
LOG.info("Features are: "+features.length());
for (int i=0; i<features.length(); i++) {
final FeatureRow row = new FeatureRow();
row.setCrsName(featureCRSName);
JSONObject theFeature = ((JSONObject)features.get(i));
LOG.debug("Building at index: "+i);
try {
JSONObject geometry = theFeature.getJSONObject("geometry");
String typeValue = geometry.getString("type");
JSONArray coordinates = geometry.getJSONArray("coordinates");
//String toCoordinates = coordinates.toString();
String x1 = coordinates.get(0).toString();
String y1 = coordinates.get(1).toString();
LOG.debug("Coordinate x1: "+x1);
LOG.debug("Coordinate y1: "+y1);
Double coordX = null;
Double coordY = null;
FeatureGeometry fg = new FeatureGeometry();
fg.setType(typeValue);
//TODO ONLY POINT GEOMETRY
try {
coordX = Double.parseDouble(x1);
coordY = Double.parseDouble(y1);
Coordinate coord = new Coordinate(coordX, coordY);
fg.setPath(new PointsPath(new Coordinate[] {coord}));
}catch (Exception e) {
LOG.warn("Not able to parse the 'coordinates' field: ",e);
}
row.setGeometry(fg);
}catch (Exception e) {
LOG.debug("Unable to pase geometry at index: "+i);
}
// // iterate properties
JSONObject properties = theFeature.getJSONObject("properties");
Map<String,List<String>> mapProperties = new HashMap<String,List<String>>();
@SuppressWarnings("unchecked")
Iterator<String> ii = properties.keys();
while (ii.hasNext()) {
String key = ii.next();
String value = properties.optString(key,"");
List<String> theValues = mapProperties.get(key);
if(theValues==null)
mapProperties.put(key, Arrays.asList(value));
else {
theValues.add(value);
mapProperties.put(key, theValues);
}
}
row.setMapProperties(mapProperties);
listFeaturesRow.add(row);
LOG.info("Added row "+row+" to exported properties");
}
} catch (IOException e) {
LOG.error("Error for layerItem name: "+layerItem.getName(), e);
} catch (JSONException e) {
LOG.error("Error for layerItem name: "+layerItem.getName(), e);
}finally{
IOUtils.closeQuietly(is);
}
LOG.info("Returning "+listFeaturesRow.size()+" features");
return listFeaturesRow;
}
}