181 lines
6.1 KiB
Java
181 lines
6.1 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.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants;
|
|
import org.gcube.portlets.user.geoportaldataviewer.server.util.URLParserUtil;
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaDataObject;
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.BoundsMap;
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem;
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureGeometry;
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureRow;
|
|
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)
|
|
*
|
|
* Oct 29, 2020
|
|
*/
|
|
public class FeatureParser {
|
|
|
|
private static Logger LOG = LoggerFactory.getLogger(FeatureParser.class);
|
|
|
|
|
|
/**
|
|
* Gets the data results.
|
|
*
|
|
* @param layerItems the layer items
|
|
* @param mapSrsName the map srs name
|
|
* @param selectBBOX the select BBOX
|
|
* @param maxWFSFeature the max WFS feature
|
|
* @return the data results
|
|
*/
|
|
public static List<GeoNaDataObject> getDataResults(List<LayerItem> layerItems, String mapSrsName, BoundsMap selectBBOX, int maxWFSFeature) {
|
|
|
|
if(maxWFSFeature<0) {
|
|
maxWFSFeature = GeoportalDataViewerConstants.MAX_WFS_FEATURES;
|
|
}
|
|
|
|
List<GeoNaDataObject> listGeonaDO = new ArrayList<GeoNaDataObject>();
|
|
//IF WFS IS AVAILABLE USE WFS REQUEST OTHERWHISE TRY TO USE WPS SERVICE
|
|
for (LayerItem layerItem : layerItems){
|
|
List<FeatureRow> rows = getWFSFeatureProperties(layerItem, mapSrsName, selectBBOX, maxWFSFeature);
|
|
GeoNaDataObject gdo = new GeoNaDataObject();
|
|
gdo.setLayerItem(layerItem);
|
|
gdo.setFeatures(rows);
|
|
listGeonaDO.add(gdo);
|
|
}
|
|
return listGeonaDO;
|
|
}
|
|
|
|
|
|
/**
|
|
* 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);
|
|
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();
|
|
row.setGeometry(new FeatureGeometry(typeValue, toCoordinates));
|
|
}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;
|
|
}
|
|
}
|