2023-05-26 14:45:47 +02:00
|
|
|
package org.gcube.portlets.user.geoportaldataviewer.client.ui.crossfiltering;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.config.GroupedLayersDV;
|
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.config.layers.CrossFilteringLayerDV;
|
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.config.layers.LayerIDV;
|
2023-06-01 16:26:34 +02:00
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GCubeSDILayer;
|
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.materialization.IndexLayerDV;
|
2023-06-07 14:26:57 +02:00
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.BBOXDV;
|
2023-05-26 14:45:47 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MAP_PROJECTION;
|
2023-06-05 16:54:40 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync;
|
2023-06-06 11:49:31 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.events.ApplyCQLToLayerOnMapEvent;
|
2023-06-07 14:26:57 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.events.FitMapToExtentEvent;
|
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.gis.ExtentWrapped;
|
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.gis.MapUtils;
|
2023-05-26 14:45:47 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.ui.util.OLGeoJSONUtil;
|
2023-06-01 16:26:34 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.util.LoaderIcon;
|
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.util.URLUtil;
|
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.client.util.WFSMakerUtil;
|
2023-05-31 17:02:03 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.GCubeCollection;
|
2023-05-26 14:45:47 +02:00
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem;
|
|
|
|
import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.GeoInformationForWMSRequest;
|
|
|
|
|
2023-06-01 16:26:34 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.Alert;
|
2023-05-31 17:02:03 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.Button;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.CheckBox;
|
|
|
|
import com.github.gwtbootstrap.client.ui.ControlGroup;
|
|
|
|
import com.github.gwtbootstrap.client.ui.ControlLabel;
|
|
|
|
import com.github.gwtbootstrap.client.ui.Controls;
|
2023-05-31 17:02:03 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.DropdownButton;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.Fieldset;
|
|
|
|
import com.github.gwtbootstrap.client.ui.ListBox;
|
2023-06-01 16:26:34 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.constants.AlertType;
|
2023-05-31 17:02:03 +02:00
|
|
|
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.google.gwt.core.client.GWT;
|
|
|
|
import com.google.gwt.event.dom.client.ChangeEvent;
|
|
|
|
import com.google.gwt.event.dom.client.ChangeHandler;
|
2023-05-31 17:02:03 +02:00
|
|
|
import com.google.gwt.event.dom.client.ClickEvent;
|
|
|
|
import com.google.gwt.event.dom.client.ClickHandler;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.google.gwt.event.shared.HandlerManager;
|
2023-05-26 17:49:59 +02:00
|
|
|
import com.google.gwt.http.client.URL;
|
2023-06-07 14:26:57 +02:00
|
|
|
import com.google.gwt.json.client.JSONArray;
|
|
|
|
import com.google.gwt.json.client.JSONObject;
|
|
|
|
import com.google.gwt.json.client.JSONParser;
|
|
|
|
import com.google.gwt.json.client.JSONValue;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.google.gwt.uibinder.client.UiBinder;
|
|
|
|
import com.google.gwt.uibinder.client.UiField;
|
2023-06-05 16:54:40 +02:00
|
|
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.google.gwt.user.client.ui.Composite;
|
2023-06-07 14:26:57 +02:00
|
|
|
import com.google.gwt.user.client.ui.FlexTable;
|
2023-06-01 16:26:34 +02:00
|
|
|
import com.google.gwt.user.client.ui.HTML;
|
|
|
|
import com.google.gwt.user.client.ui.HTMLPanel;
|
2023-05-26 14:45:47 +02:00
|
|
|
import com.google.gwt.user.client.ui.Widget;
|
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
import jsinterop.base.JsPropertyMap;
|
2023-06-07 14:26:57 +02:00
|
|
|
import ol.Coordinate;
|
|
|
|
import ol.Extent;
|
2023-05-26 14:45:47 +02:00
|
|
|
import ol.Feature;
|
2023-06-07 14:26:57 +02:00
|
|
|
import ol.OLFactory;
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The Class CrossFilteringLayerPanel.
|
|
|
|
*
|
|
|
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
|
|
|
*
|
|
|
|
* May 15, 2023
|
|
|
|
*/
|
|
|
|
public class CrossFilteringLayerPanel extends Composite {
|
|
|
|
|
2023-06-06 14:38:30 +02:00
|
|
|
private static final String ITEM_LABEL = "centroid";
|
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
public static String COLORSCALERANGE = "COLORSCALERANGE";
|
|
|
|
|
|
|
|
@UiField
|
|
|
|
Fieldset fieldSet;
|
|
|
|
|
2023-06-01 16:26:34 +02:00
|
|
|
@UiField
|
|
|
|
HTMLPanel panelResults;
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
@UiField
|
|
|
|
Button buttonReset;
|
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
private CheckBox checkbox;
|
|
|
|
|
|
|
|
private GeoInformationForWMSRequest geoInformation;
|
|
|
|
|
|
|
|
private static CrossFilteringLayerPanelUiBinder uiBinder = GWT.create(CrossFilteringLayerPanelUiBinder.class);
|
|
|
|
|
|
|
|
private HandlerManager applicationBus;
|
|
|
|
|
|
|
|
private LayerItem layerItem;
|
|
|
|
|
|
|
|
private LinkedHashMap<Integer, List<? extends LayerIDV>> mapInnestedFiltering = new LinkedHashMap<Integer, List<? extends LayerIDV>>();
|
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
private LinkedHashMap<Integer, HashMap<String, SelectableItem>> mapInnestedFeatures = new LinkedHashMap<Integer, HashMap<String, SelectableItem>>();
|
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
private LinkedHashMap<Integer, List<ListBox>> mapInnestedListBoxes = new LinkedHashMap<Integer, List<ListBox>>();
|
|
|
|
|
|
|
|
private GroupedLayersDV<? extends LayerIDV> groupedLayersDV;
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
private GCubeCollection gCubeCollection;
|
|
|
|
|
|
|
|
private DropdownButton filterButton;
|
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
/**
|
|
|
|
* The Interface LayerCollectionPanelUiBinder.
|
|
|
|
*
|
|
|
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
|
|
|
*
|
|
|
|
* Jan 16, 2023
|
|
|
|
*/
|
|
|
|
interface CrossFilteringLayerPanelUiBinder extends UiBinder<Widget, CrossFilteringLayerPanel> {
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Instantiates a new overlay custom layer panel.
|
|
|
|
*
|
|
|
|
* @param gCubeCollection the g cube collection
|
|
|
|
* @param groupedLayersDV the grouped layers DV
|
|
|
|
* @param applicationBus the application bus
|
|
|
|
*/
|
|
|
|
public CrossFilteringLayerPanel(GCubeCollection gCubeCollection,
|
|
|
|
GroupedLayersDV<? extends LayerIDV> groupedLayersDV, HandlerManager applicationBus) {
|
|
|
|
initWidget(uiBinder.createAndBindUi(this));
|
|
|
|
this.applicationBus = applicationBus;
|
|
|
|
this.groupedLayersDV = groupedLayersDV;
|
|
|
|
this.gCubeCollection = gCubeCollection;
|
|
|
|
GWT.log("Building cross-filtering for: " + groupedLayersDV);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
buttonReset.setType(ButtonType.LINK);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
int level = 0;
|
|
|
|
// Building mapInnestedFiltering
|
|
|
|
recursivelyBuildSelectableLevels(level, groupedLayersDV.getListCustomLayers());
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
GWT.log("cross-filtering mapInnestedFiltering: " + mapInnestedFiltering);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
for (Integer theLevel : mapInnestedFiltering.keySet()) {
|
|
|
|
addListBoxesLevelToPanel(theLevel, mapInnestedFiltering.get(theLevel));
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
fillSelectableLevel(level, null);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
bindEvents();
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
}
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Bind events.
|
|
|
|
*/
|
|
|
|
private void bindEvents() {
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
buttonReset.addClickHandler(new ClickHandler() {
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
@Override
|
|
|
|
public void onClick(ClickEvent event) {
|
2023-06-01 16:26:34 +02:00
|
|
|
panelResults.clear();
|
2023-05-31 17:02:03 +02:00
|
|
|
for (int i = 1; i < mapInnestedListBoxes.size(); i++) {
|
|
|
|
resetListBoxLevel(i);
|
|
|
|
}
|
|
|
|
// Selecting the placeholder of the fist list box
|
|
|
|
List<ListBox> listBox = mapInnestedListBoxes.get(0);
|
|
|
|
listBox.get(0).setSelectedIndex(0);
|
|
|
|
// Resetting CQL filtering
|
2023-06-06 11:49:31 +02:00
|
|
|
applicationBus.fireEvent(new ApplyCQLToLayerOnMapEvent(gCubeCollection.getIndexes().get(0), null));
|
2023-05-31 17:02:03 +02:00
|
|
|
setFilterHighLighted(false);
|
|
|
|
}
|
|
|
|
});
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Recursively build selectable levels.
|
|
|
|
*
|
|
|
|
* @param level the level
|
|
|
|
* @param layersIDV the layers IDV
|
|
|
|
*/
|
2023-05-26 14:45:47 +02:00
|
|
|
private void recursivelyBuildSelectableLevels(int level, List<? extends LayerIDV> layersIDV) {
|
|
|
|
|
|
|
|
if (layersIDV == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
mapInnestedFiltering.put(level, layersIDV);
|
|
|
|
|
|
|
|
for (LayerIDV layerIDV : layersIDV) {
|
|
|
|
if (layerIDV instanceof CrossFilteringLayerDV) {
|
|
|
|
CrossFilteringLayerDV crossFilteringLayer = (CrossFilteringLayerDV) layerIDV;
|
|
|
|
|
|
|
|
if (crossFilteringLayer.getRelated_to() != null) {
|
|
|
|
recursivelyBuildSelectableLevels(++level, crossFilteringLayer.getRelated_to());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-05-31 17:02:03 +02:00
|
|
|
* Fill selectable level.
|
2023-05-26 14:45:47 +02:00
|
|
|
*
|
2023-05-31 17:02:03 +02:00
|
|
|
* @param level the level
|
|
|
|
* @param selectedItem the selected item
|
2023-05-26 14:45:47 +02:00
|
|
|
*/
|
2023-05-31 17:02:03 +02:00
|
|
|
private void fillSelectableLevel(int level, SelectableItem selectedItem) {
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
List<? extends LayerIDV> layersIDV = mapInnestedFiltering.get(level);
|
|
|
|
List<ListBox> listBoxes = mapInnestedListBoxes.get(level);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
if (layersIDV == null)
|
|
|
|
return;
|
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
final HashMap<String, SelectableItem> mapSelectableFeatures = new HashMap<String, CrossFilteringLayerPanel.SelectableItem>();
|
|
|
|
|
|
|
|
LayerIDV layerIDV = layersIDV.get(0); // Expected one
|
|
|
|
|
|
|
|
if (layerIDV instanceof CrossFilteringLayerDV) {
|
|
|
|
CrossFilteringLayerDV crossFilteringLayer = (CrossFilteringLayerDV) layerIDV;
|
|
|
|
String wfsURL = crossFilteringLayer.getWFS_URL();
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
if (selectedItem != null) {
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
String cqlFilterValue = crossFilteringLayer.getTable_parent_key_field() + "=" + selectedItem.keyValue;
|
2023-06-01 16:26:34 +02:00
|
|
|
wfsURL += "&" + WFSMakerUtil.CQL_FILTER_PARAMETER + "=" + URL.encode(cqlFilterValue);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
}
|
|
|
|
GWT.log("wfsURL request: " + wfsURL);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
GeoportalDataViewerServiceAsync.Util.getInstance().getHTTPResponseForURL(wfsURL,
|
|
|
|
new AsyncCallback<String>() {
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
@Override
|
|
|
|
public void onSuccess(String response) {
|
|
|
|
GWT.log("wfsURL response: " + response);
|
|
|
|
Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, response);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
for (Feature feature : features) {
|
|
|
|
JsPropertyMap<Object> properties = feature.getProperties();
|
|
|
|
Object keyValue = properties.get(crossFilteringLayer.getTable_key_field());
|
|
|
|
Object itemField = properties.get(crossFilteringLayer.getTable_show_field());
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
Object parentKey = null;
|
|
|
|
if (crossFilteringLayer.getTable_parent_key_field() != null
|
|
|
|
&& !crossFilteringLayer.getTable_parent_key_field().isEmpty())
|
|
|
|
parentKey = properties.get(crossFilteringLayer.getTable_parent_key_field());
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
parentKey = parentKey == null ? "" : parentKey;
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
SelectableItem selectableItem = new SelectableItem(
|
|
|
|
crossFilteringLayer.getTable_key_field() + "", keyValue + "",
|
|
|
|
crossFilteringLayer.getTable_parent_key_field(), itemField + "",
|
|
|
|
crossFilteringLayer.getName(), crossFilteringLayer.getTable_geometry_name());
|
|
|
|
GWT.log("selectableItem: " + selectableItem);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
String pathFeatureKey = pathFeatureKey(selectableItem);
|
|
|
|
mapSelectableFeatures.put(pathFeatureKey, selectableItem);
|
2023-05-26 17:49:59 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
}
|
|
|
|
GWT.log("mapSelectableFeatures: " + mapSelectableFeatures);
|
|
|
|
mapInnestedFeatures.put(level, mapSelectableFeatures);
|
|
|
|
String placholder = placeholderLayer(layersIDV.get(0)); // Expected one
|
|
|
|
fillListBoxLevel(level, mapSelectableFeatures, listBoxes, placholder);
|
2023-05-26 17:49:59 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
@Override
|
|
|
|
public void onFailure(Throwable caught) {
|
|
|
|
panelResults.clear();
|
|
|
|
HTML error = new HTML(
|
|
|
|
"Sorry, an issue is occurred on loading data for cross-filtering facility. Error is: "
|
|
|
|
+ caught.getMessage());
|
|
|
|
panelResults.add(error);
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Path feature key.
|
|
|
|
*
|
|
|
|
* @param selectableItem the selectable item
|
|
|
|
* @return the string
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
private String pathFeatureKey(SelectableItem selectableItem) {
|
2023-05-31 17:02:03 +02:00
|
|
|
return "root_" + selectableItem.parentKeyField + "_" + selectableItem.keyField + "_" + selectableItem.keyValue;
|
2023-05-26 17:49:59 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Placeholder layer.
|
|
|
|
*
|
|
|
|
* @param layersIDV the layers IDV
|
|
|
|
* @return the string
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
private String placeholderLayer(LayerIDV layersIDV) {
|
2023-05-31 17:02:03 +02:00
|
|
|
String placeholder = "Select";
|
2023-06-06 12:04:25 +02:00
|
|
|
// if (layersIDV != null)
|
|
|
|
// placeholder += " " + layersIDV.getTitle();
|
2023-05-31 17:02:03 +02:00
|
|
|
|
|
|
|
placeholder += " ...";
|
|
|
|
return placeholder;
|
2023-05-26 17:49:59 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Adds the list boxes level to panel.
|
|
|
|
*
|
|
|
|
* @param level the level
|
|
|
|
* @param layersIDV the layers IDV
|
|
|
|
*/
|
2023-05-26 14:45:47 +02:00
|
|
|
private void addListBoxesLevelToPanel(int level, List<? extends LayerIDV> layersIDV) {
|
|
|
|
|
|
|
|
if (layersIDV == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
List<ListBox> listBoxes = new ArrayList<ListBox>(layersIDV.size());
|
|
|
|
|
|
|
|
for (LayerIDV layerIDV : layersIDV) {
|
|
|
|
ControlGroup cg = new ControlGroup();
|
|
|
|
ControlLabel cl = new ControlLabel(layerIDV.getTitle());
|
|
|
|
Controls controls = new Controls();
|
|
|
|
ListBox listBox = new ListBox();
|
2023-05-26 17:49:59 +02:00
|
|
|
String placeholder = placeholderLayer(layerIDV);
|
|
|
|
listBox.addItem(placeholder);
|
|
|
|
setEnabledBox(listBox, false);
|
2023-05-26 14:45:47 +02:00
|
|
|
listBoxes.add(listBox);
|
|
|
|
controls.add(listBox);
|
|
|
|
cg.add(cl);
|
|
|
|
cg.add(controls);
|
2023-05-26 17:49:59 +02:00
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
fieldSet.add(cg);
|
|
|
|
}
|
|
|
|
|
|
|
|
mapInnestedListBoxes.put(level, listBoxes);
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Sets the enabled box.
|
|
|
|
*
|
|
|
|
* @param listBox the list box
|
|
|
|
* @param bool the bool
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
public void setEnabledBox(ListBox listBox, boolean bool) {
|
|
|
|
listBox.setEnabled(bool);
|
|
|
|
}
|
2023-05-31 17:02:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear list box.
|
|
|
|
*
|
|
|
|
* @param listBox the list box
|
|
|
|
* @param bool the bool
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
public void clearListBox(ListBox listBox, boolean bool) {
|
|
|
|
listBox.setEnabled(bool);
|
|
|
|
}
|
2023-05-31 17:02:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reset list box level.
|
|
|
|
*
|
|
|
|
* @param level the level
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
private void resetListBoxLevel(int level) {
|
2023-05-31 17:02:03 +02:00
|
|
|
|
2023-05-26 17:49:59 +02:00
|
|
|
List<ListBox> listBoxes = mapInnestedListBoxes.get(level);
|
2023-05-31 17:02:03 +02:00
|
|
|
if (listBoxes != null) {
|
2023-05-26 17:49:59 +02:00
|
|
|
for (ListBox listBox : listBoxes) {
|
|
|
|
listBox.clear();
|
|
|
|
setEnabledBox(listBox, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Fill list box level.
|
|
|
|
*
|
|
|
|
* @param level the level
|
|
|
|
* @param mapSelectableFeatures the map selectable features
|
|
|
|
* @param listBoxes the list boxes
|
|
|
|
* @param placeholder the placeholder
|
|
|
|
*/
|
2023-05-26 14:45:47 +02:00
|
|
|
private void fillListBoxLevel(int level, HashMap<String, SelectableItem> mapSelectableFeatures,
|
2023-05-26 17:49:59 +02:00
|
|
|
List<ListBox> listBoxes, String placeholder) {
|
2023-06-01 16:26:34 +02:00
|
|
|
// GWT.log("fillBox level: " + level + " map: " + mapSelectableFeatures);
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
if (mapSelectableFeatures == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ListBox listBox = listBoxes.get(0); // Expected one
|
2023-05-26 17:49:59 +02:00
|
|
|
listBox.clear();
|
|
|
|
listBox.addItem(placeholder);
|
|
|
|
listBox.getElement().getFirstChildElement().setAttribute("disabled", "disabled");
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
for (String key : mapSelectableFeatures.keySet()) {
|
|
|
|
SelectableItem selItem = mapSelectableFeatures.get(key);
|
2023-05-31 17:02:03 +02:00
|
|
|
listBox.addItem(selItem.itemValue, key);
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
listBox.addChangeHandler(new ChangeHandler() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onChange(ChangeEvent event) {
|
2023-05-26 17:49:59 +02:00
|
|
|
loadInnerLevel(level, listBox.getSelectedValue());
|
2023-05-31 17:02:03 +02:00
|
|
|
|
|
|
|
for (int i = level + 1; i < mapInnestedListBoxes.size(); i++) {
|
|
|
|
resetListBoxLevel(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
String key = listBox.getSelectedValue();
|
|
|
|
SelectableItem selectableItem = mapSelectableFeatures.get(key);
|
|
|
|
buildCrossFilteringCQLAndFireEvent(selectableItem);
|
|
|
|
setFilterHighLighted(true);
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|
2023-05-31 17:02:03 +02:00
|
|
|
|
2023-05-26 14:45:47 +02:00
|
|
|
});
|
2023-05-26 17:49:59 +02:00
|
|
|
|
|
|
|
setEnabledBox(listBox, true);
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Builds the cross filtering CQL and fire event.
|
|
|
|
*
|
|
|
|
* @param selectableItem the selectable item
|
|
|
|
*/
|
|
|
|
private void buildCrossFilteringCQLAndFireEvent(SelectableItem selectableItem) {
|
|
|
|
String setCqlFilter = "INTERSECTS(geom,querySingle('" + selectableItem.layername + "','"
|
|
|
|
+ selectableItem.theGeometryName + "','" + selectableItem.keyField + "=''" + selectableItem.keyValue
|
2023-06-01 16:26:34 +02:00
|
|
|
+ "'''))";
|
|
|
|
// setCqlFilter = URL.encode(setCqlFilter);
|
2023-05-31 17:02:03 +02:00
|
|
|
GWT.log("CQL FILTER built: " + setCqlFilter);
|
|
|
|
|
2023-06-01 16:26:34 +02:00
|
|
|
IndexLayerDV indexLayer = gCubeCollection.getIndexes().get(0);
|
|
|
|
|
|
|
|
try {
|
|
|
|
GCubeSDILayer layer = indexLayer.getLayer();
|
|
|
|
String wmsLink = layer.getOgcLinks().get("wms");
|
|
|
|
String layerName = URLUtil.extractValueOfParameterFromURL("layers", wmsLink);
|
|
|
|
String serviceURL = URLUtil.getPathURL(wmsLink);
|
|
|
|
String toLServiceURL = serviceURL.toLowerCase();
|
|
|
|
if (toLServiceURL.endsWith("wms")) {
|
|
|
|
toLServiceURL = toLServiceURL.substring(0, toLServiceURL.length() - 3) + "ows";
|
|
|
|
}
|
|
|
|
String wfsCrossFilteringQuery = WFSMakerUtil.buildWFSRequest(toLServiceURL, layerName, 1000, "geom",
|
|
|
|
setCqlFilter);
|
|
|
|
GWT.log("wfsCrossFilteringQuery: " + wfsCrossFilteringQuery);
|
|
|
|
showCountResultsOfWFSCrossFiltering(wfsCrossFilteringQuery);
|
|
|
|
} catch (Exception e) {
|
|
|
|
// TODO: handle exception
|
|
|
|
}
|
2023-06-05 16:54:40 +02:00
|
|
|
|
2023-06-06 11:49:31 +02:00
|
|
|
applicationBus.fireEvent(new ApplyCQLToLayerOnMapEvent(indexLayer, setCqlFilter));
|
2023-06-01 16:26:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void showCountResultsOfWFSCrossFiltering(String wfsQuery) {
|
|
|
|
|
|
|
|
panelResults.clear();
|
|
|
|
panelResults.add(new HTML("<hr>"));
|
2023-06-05 16:54:40 +02:00
|
|
|
panelResults.add(new LoaderIcon("Applying spatial filter..."));
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
GeoportalDataViewerServiceAsync.Util.getInstance().getHTTPResponseForURL(wfsQuery, new AsyncCallback<String>() {
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
@Override
|
|
|
|
public void onFailure(Throwable caught) {
|
|
|
|
panelResults.clear();
|
|
|
|
panelResults.add(new HTML("<hr>"));
|
|
|
|
Alert alert = new Alert("Error on returning number of items");
|
|
|
|
alert.setType(AlertType.ERROR);
|
|
|
|
alert.setClose(false);
|
|
|
|
panelResults.add(alert);
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
}
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
@Override
|
|
|
|
public void onSuccess(String response) {
|
|
|
|
Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, response);
|
2023-06-07 14:26:57 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
if (features != null) {
|
|
|
|
int dataCount = features.length;
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
panelResults.clear();
|
|
|
|
panelResults.add(new HTML("<hr>"));
|
2023-06-07 14:26:57 +02:00
|
|
|
|
|
|
|
FlexTable flexTable = new FlexTable();
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
String message = "";
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
if (dataCount <= 0) {
|
2023-06-06 14:50:06 +02:00
|
|
|
message = "No "+ITEM_LABEL+" found";
|
2023-06-05 16:54:40 +02:00
|
|
|
} else {
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
message = "Found " + dataCount;
|
2023-06-06 14:38:30 +02:00
|
|
|
message += dataCount > 1 ? " " + ITEM_LABEL + "s" : " " + ITEM_LABEL;
|
2023-06-01 16:26:34 +02:00
|
|
|
}
|
2023-06-05 16:54:40 +02:00
|
|
|
HTML resultMessage = new HTML();
|
|
|
|
resultMessage.getElement().addClassName("search_result_msg");
|
|
|
|
resultMessage.setHTML(message);
|
2023-06-07 14:26:57 +02:00
|
|
|
flexTable.setWidget(0, 0, resultMessage.asWidget());
|
|
|
|
panelResults.add(flexTable);
|
|
|
|
|
|
|
|
try {
|
|
|
|
JSONObject jObject = (JSONObject) JSONParser.parseStrict(response);
|
|
|
|
JSONArray bbox = (JSONArray) jObject.get("bbox");
|
|
|
|
double[] coords = new double[bbox.size()];
|
|
|
|
for (int i = 0; i < bbox.size(); i++) {
|
|
|
|
JSONValue coord = bbox.get(i);
|
|
|
|
coords[i] = Double.parseDouble(coord.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
//Inverting coordinate to lat/long for EPSG:3857 Pseudo-Mercator
|
|
|
|
Coordinate lower = OLFactory.createCoordinate(coords[1], coords[0]);
|
|
|
|
Coordinate lowerCoord = MapUtils.transformCoordiante(lower, MAP_PROJECTION.EPSG_4326.getName(),
|
|
|
|
MAP_PROJECTION.EPSG_3857.getName());
|
|
|
|
|
|
|
|
Coordinate upper = OLFactory.createCoordinate(coords[3], coords[2]);
|
|
|
|
Coordinate upperCoord = MapUtils.transformCoordiante(upper, MAP_PROJECTION.EPSG_4326.getName(),
|
|
|
|
MAP_PROJECTION.EPSG_3857.getName());
|
|
|
|
|
|
|
|
final Extent transfExtent = new ExtentWrapped(lowerCoord.getX(), lowerCoord.getY(), upperCoord.getX(), upperCoord.getY());
|
|
|
|
GWT.log("Zoom to selected - transf extent: "+transfExtent);
|
|
|
|
|
|
|
|
|
|
|
|
Button selectTo = new Button("Zoom to selected");
|
|
|
|
selectTo.setType(ButtonType.DEFAULT);
|
|
|
|
selectTo.addClickHandler(new ClickHandler() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(ClickEvent event) {
|
|
|
|
applicationBus.fireEvent(new FitMapToExtentEvent(transfExtent));
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
flexTable.setWidget(1,0,selectTo);
|
|
|
|
//panelResults.add(selectTo);
|
|
|
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
// TODO: handle exception
|
|
|
|
}
|
2023-06-01 16:26:34 +02:00
|
|
|
}
|
2023-06-07 14:26:57 +02:00
|
|
|
|
|
|
|
|
2023-06-01 16:26:34 +02:00
|
|
|
|
2023-06-05 16:54:40 +02:00
|
|
|
}
|
|
|
|
});
|
2023-05-31 17:02:03 +02:00
|
|
|
}
|
2023-06-07 14:26:57 +02:00
|
|
|
|
|
|
|
public static final BBOXDV fromGeoJSON(double[] coords) {
|
|
|
|
BBOXDV toReturn = new BBOXDV();
|
|
|
|
toReturn.setMaxX(coords[0]);
|
|
|
|
toReturn.setMinY(coords[1]);
|
|
|
|
|
|
|
|
if (coords.length == 6) {
|
|
|
|
// 3D
|
|
|
|
toReturn.setMinZ(coords[2]);
|
|
|
|
toReturn.setMinX(coords[3]);
|
|
|
|
toReturn.setMaxY(coords[4]);
|
|
|
|
toReturn.setMaxZ(coords[5]);
|
|
|
|
} else {
|
|
|
|
toReturn.setMinX(coords[2]);
|
|
|
|
toReturn.setMaxY(coords[3]);
|
|
|
|
}
|
|
|
|
return toReturn;
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Load inner level.
|
|
|
|
*
|
|
|
|
* @param level the level
|
|
|
|
* @param selectableItemValue the selectable item value
|
|
|
|
*/
|
2023-05-26 17:49:59 +02:00
|
|
|
private void loadInnerLevel(int level, String selectableItemValue) {
|
2023-06-01 16:26:34 +02:00
|
|
|
// GWT.log("selected level " + level + " selectableItemValue " +
|
|
|
|
// selectableItemValue);
|
2023-05-26 17:49:59 +02:00
|
|
|
HashMap<String, SelectableItem> mapSelectableItem = mapInnestedFeatures.get(level);
|
|
|
|
SelectableItem selectedItem = mapSelectableItem.get(selectableItemValue);
|
|
|
|
|
2023-06-01 16:26:34 +02:00
|
|
|
// GWT.log("selected selectableItem " + selectedItem);
|
2023-05-26 17:49:59 +02:00
|
|
|
int innerLevel = level + 1;
|
|
|
|
List<? extends LayerIDV> selectedLayers = mapInnestedFiltering.get(innerLevel);
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
// if layer filtering exists at this level
|
2023-05-26 17:49:59 +02:00
|
|
|
if (selectedLayers != null) {
|
|
|
|
|
|
|
|
List<ListBox> selectedListBoxes = mapInnestedListBoxes.get(innerLevel);
|
|
|
|
GWT.log("loading inner layers " + selectedLayers);
|
|
|
|
GWT.log("loading selectedListBoxes " + selectedListBoxes);
|
2023-05-31 17:02:03 +02:00
|
|
|
fillSelectableLevel(innerLevel, selectedItem);
|
2023-05-26 17:49:59 +02:00
|
|
|
}
|
2023-05-26 14:45:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Sets the filter high lighted.
|
|
|
|
*
|
|
|
|
* @param bool the new filter high lighted
|
|
|
|
*/
|
|
|
|
private void setFilterHighLighted(boolean bool) {
|
|
|
|
if (bool) {
|
|
|
|
filterButton.getElement().addClassName("highlight-button");
|
|
|
|
} else {
|
|
|
|
filterButton.getElement().removeClassName("highlight-button");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the search button.
|
|
|
|
*
|
|
|
|
* @param searchFacilityButton the new search button
|
|
|
|
*/
|
|
|
|
public void setFilterButton(DropdownButton searchFacilityButton) {
|
|
|
|
this.filterButton = searchFacilityButton;
|
|
|
|
|
|
|
|
}
|
2023-05-26 14:45:47 +02:00
|
|
|
|
2023-05-31 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* The Class SelectableItem.
|
|
|
|
*
|
|
|
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
|
|
|
*
|
|
|
|
* May 31, 2023
|
|
|
|
*/
|
|
|
|
public class SelectableItem {
|
|
|
|
protected String keyField;
|
|
|
|
protected String keyValue;
|
|
|
|
protected String parentKeyField;
|
|
|
|
protected String itemValue;
|
|
|
|
protected String layername;
|
|
|
|
protected String theGeometryName;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instantiates a new selectable item.
|
|
|
|
*/
|
|
|
|
SelectableItem() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instantiates a new selectable item.
|
|
|
|
*
|
|
|
|
* @param keyField the key field
|
|
|
|
* @param keyValue the key value
|
|
|
|
* @param parentKeyField the parent key field
|
|
|
|
* @param itemValue the item value
|
|
|
|
* @param layername the layername
|
|
|
|
* @param theGeometryName the the geometry name
|
|
|
|
*/
|
|
|
|
public SelectableItem(String keyField, String keyValue, String parentKeyField, String itemValue,
|
|
|
|
String layername, String theGeometryName) {
|
|
|
|
super();
|
|
|
|
this.keyField = keyField;
|
|
|
|
this.keyValue = keyValue;
|
|
|
|
this.parentKeyField = parentKeyField;
|
|
|
|
this.itemValue = itemValue;
|
|
|
|
this.layername = layername;
|
|
|
|
this.theGeometryName = theGeometryName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* To string.
|
|
|
|
*
|
|
|
|
* @return the string
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
|
|
builder.append("SelectableItem [keyField=");
|
|
|
|
builder.append(keyField);
|
|
|
|
builder.append(", keyValue=");
|
|
|
|
builder.append(keyValue);
|
|
|
|
builder.append(", parentKeyField=");
|
|
|
|
builder.append(parentKeyField);
|
|
|
|
builder.append(", itemValue=");
|
|
|
|
builder.append(itemValue);
|
|
|
|
builder.append(", layername=");
|
|
|
|
builder.append(layername);
|
|
|
|
builder.append(", theGeometryName=");
|
|
|
|
builder.append(theGeometryName);
|
|
|
|
builder.append("]");
|
|
|
|
return builder.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-05-26 14:45:47 +02:00
|
|
|
}
|