Skip to content

Commit

Permalink
Merge branch 'feature/089-getFeatureInfo' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
p-a-s-c-a-l committed Jul 1, 2020
2 parents 4a0188f + e44445d commit 33a3c6f
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 89 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"leaflet-providers": "git://github.com/leaflet-extras/leaflet-providers#semver:^1.8.0",
"leaflet.nontiledlayer": "^1.0.8",
"leaflet.sync": "^0.2.4",
"leaflet.wms": "^0.2.0",
"loglevel": "^1.6.7",
"prop-types": "latest",
"query-string": "^6.11.1",
Expand All @@ -27,7 +28,8 @@
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"turf": "latest",
"wicket": "^1.3.5"
"wicket": "^1.3.5",
"xml-js": "^1.6.11"
},
"resolutions": {
"js-yaml": "^3.13.1",
Expand Down
8 changes: 4 additions & 4 deletions src/components/GenericMap.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import log from 'loglevel';

import MapComponent from './commons/MapComponent';
import LeafletMap from './commons/LeafletMap';
import BasicMap from './commons/BasicMap';

// yes, order of imports do matter
Expand Down Expand Up @@ -65,7 +65,7 @@ export default class GenericMap extends BasicMap {
if (this.props.isSynchronised === true) {
log.info('rendering two sychronised maps: ' + this.props.isSynchronised);
return (<>
<MapComponent
<LeafletMap
loading={this.state.loading}
bounds={this.state.bounds}
baseLayers={this.state.baseLayers}
Expand All @@ -76,7 +76,7 @@ export default class GenericMap extends BasicMap {
ref={(mapComponent) => (this.mapComponentA = mapComponent)}
fly='true'
/>
<MapComponent
<LeafletMap
loading={this.state.loading}
bounds={this.state.bounds}
baseLayers={this.state.baseLayers}
Expand All @@ -91,7 +91,7 @@ export default class GenericMap extends BasicMap {
} else {
log.info('rendering one simple map: ' + this.props.isSynchronised);
return (
<MapComponent
<LeafletMap
loading={this.state.loading}
bounds={this.state.bounds}
baseLayers={this.state.baseLayers}
Expand Down
1 change: 1 addition & 0 deletions src/components/commons/BasicMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ log.enableAll();
/**
* This is the basic class of all map classes.
* It implements the common way to extract the overlay layers from the study.
* Why is it called map? I fact it's a wrapper component for a wrapper component that wraps a leaflet map. :o
*
*
* TODO: transform to functional component. See https://github.com/clarity-h2020/simple-table-component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { ReactLeafletGroupedLayerControl as ReactLeafletGroupedLayerControlForLe
import turf from 'turf';
import 'leaflet-loading';
import LegendComponent from './LegendComponent.js';
import WMSLayer from './WMSLayer.js';
import 'leaflet/dist/leaflet.css';
import log from 'loglevel';

log.enableAll();

// See https://github.com/mhasbie/react-leaflet-vectorgrid#usage-with-react-leaflet-v2
const ReactLeafletGroupedLayerControl = withLeaflet(ReactLeafletGroupedLayerControlForLeafletv1);

/**
* Render a leaflet map with the given layers.
* This is still not the actual leaflet component but another wrapper.
* This is still not the actual leaflet component but yet another wrapper. :o
*/
export default class MapComponent extends React.Component {
export default class LeafletMap extends React.Component {
constructor(props) {
super(props);
this.state = {
Expand All @@ -25,7 +28,6 @@ export default class MapComponent extends React.Component {
checkedBaseLayer: props.baseLayers[0].name,
overlays: props.overlays,
exclusiveGroups: props.exclusiveGroups,
oldOverlay: [],
mapId: props.mapId ? props.mapId : 'simpleMap'
};

Expand Down Expand Up @@ -271,36 +273,10 @@ export default class MapComponent extends React.Component {
this.setState({ count: this.state.count + 1 });
}

/**
* Changes the overlay layer of the map.
* This method will be invoked, when the user selects an other overlay layer.
* It is only one checked overlay layer allowed
*
* @param {Array} newOverlays
* @deprecated
*/
overlayChange(newOverlays) {
if (this.state.oldOverlay != null) {
for (var i = 0; i < newOverlays.length && i < this.state.oldOverlay.length; ++i) {
if (
this.state.oldOverlay[i].name === newOverlays[i].name &&
newOverlays[i].checked &&
this.state.oldOverlay[i].checked === newOverlays[i].checked
) {
newOverlays[i].checked = false;
}
}
}

this.setState({
overlays: [...newOverlays],
count: this.state.count + 1,
oldOverlay: newOverlays
});
}

onOverlayChange(newOverlays) {
log.debug('onOverlayChange: newOverlays=' + newOverlays.length);
this.overlaysAllTogether = [...newOverlays];
log.debug('onOverlayChange: overlaysAllTogether=' + newOverlays.length);
this.setState({
overlays: [...newOverlays],
count: this.state.count + 1
Expand Down Expand Up @@ -395,31 +371,61 @@ export default class MapComponent extends React.Component {
return '';
}


/**
* Creates the jsx code for the overlay layers, that can be used in the render method
* Creates the jsx code for the **overlay** layers, that can be used in the render method
*
* @param {Object[]} layers the array with all overlay layers
* @param {Object[]} overlays the array with all overlay layers
* @returns the array with all overlay layers
*/
createLayers(layers) {
createLayers(overlays) {
var layerArray = [];
var opac = 0.5;

for (var i = 0; i < layers.length; ++i) {
var layer = layers[i];
if (layer.checked) {
const selectedOverlays = overlays.filter(overlay => overlay.checked);
log.info(`${selectedOverlays.length} overlays of total ${overlays.length} selected`);

for (var i = selectedOverlays.length - 1; i >= 0; i--) {
var overlay = selectedOverlays[i];
var j = 0;
if (overlay.groupTitle === 'Backgrounds' || overlay.groupTitle === 'CLARITY Backgrounds') {
// load background layers as tile layer and load them first
layerArray.push(
<WMSTileLayer
layers={this.getLayers(layer.name)}
url={this.getUrl(layer.name)}
key={`Backgrounds_${overlay.name}`}
layers={this.getLayers(overlay.name)}
url={this.getUrl(overlay.name)}
transparent="true"
format="image/png"
opacity="0.5"
styles={this.getStyle(overlay.name)}
tileSize={1536}
attribution={this.getAttribution(overlay.name)}
/>
);
j++;
log.debug('Background layer ' + overlay.name + ' created');
}
else {
// enable getFeatureInfo on the **last** selected layer
// this does not work! previously created layers are not updated thanks to react Virtual DOM :(
// const identify = (i - j) === (selectedOverlays.length - j - 1);
const identify = true;
layerArray.unshift(
<WMSLayer
key={overlay.name}
layers={this.getLayers(overlay.name)}
url={this.getUrl(overlay.name)}
transparent="true"
format="image/png"
opacity={opac}
styles={this.getStyle(layer.name)}
opacity="0.5"
styles={this.getStyle(overlay.name)}
tileSize={1536}
attribution={this.getAttribution()}
attribution={this.getAttribution(overlay.name)}
info_format="application/json"
identify={identify}
/>
);
log.debug(`Layer #${i} "${overlay.name}" created, getFeatureInfo: ${identify}`);
}
}

Expand All @@ -443,6 +449,7 @@ export default class MapComponent extends React.Component {
url = url.substring(0, url.indexOf('?'));
}
var checkedObj = {
key: obj.name,
checked: obj.checked,
style: this.getStyle(obj.name),
layers: this.getLayers(obj.name),
Expand Down Expand Up @@ -495,16 +502,18 @@ export default class MapComponent extends React.Component {
* Renders the map
*/
render() {
var studyAreaStyle = {
const studyAreaStyle = {
color: '#ff0000',
weight: 2,
opacity: 0.2,
fillOpacity: 0.0,
dashArray: '4 1'
};
var overlays = this.state.overlays;
const overlays = this.state.overlays;
const activeLayers = this.createLayers(overlays);
log.info(activeLayers.length + ' of ' + overlays.length + ' layers activated');

var mapElement = (
const mapElement = (
<div>
{/*
Refs provide a way to access DOM nodes or React elements created in the render method.
Expand All @@ -523,7 +532,6 @@ export default class MapComponent extends React.Component {
>
<ZoomControl
position="topleft">

</ZoomControl>
<LeafletConsumer>
{(context) => {
Expand All @@ -535,7 +543,7 @@ export default class MapComponent extends React.Component {
<GeoJSON style={studyAreaStyle} data={this.props.studyAreaPolygon} />
)}
<TileLayer noWrap={true} url={this.tileLayerUrl} />
{this.createLayers(this.state.overlays)}
{activeLayers}
<ReactLeafletGroupedLayerControl
ref={(layerControl) => (this.layerControl = layerControl)}
position="topright"
Expand All @@ -556,7 +564,7 @@ export default class MapComponent extends React.Component {
}
}

MapComponent.propTypes = {
LeafletMap.propTypes = {
loading: PropTypes.bool,
bounds: PropTypes.array,
baseLayers: PropTypes.array,
Expand Down
14 changes: 7 additions & 7 deletions src/components/commons/LegendComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ export default class LegendComponent extends React.Component {
/**
* Creates jsx code to render the legends
*
* @param {Array} legends an array with the layer that should be used for the legend
* @param {Array} layers an array with the layer that should be used for the legend
*/
createLegend(legends) {
var layerArray = [];
createLegend(layers) {
var legends = [];

for (var i = 0; i < legends.length; ++i) {
if (legends[i].checked) {
layerArray.push(<SingleLegend layer={legends[i]} caps={this.caps} />);
for (var i = 0; i < layers.length; ++i) {
if (layers[i].checked) {
legends.push(<SingleLegend key={i} layer={layers[i]} caps={this.caps} />);
}
}

return layerArray;
return legends;
}

/**
Expand Down
Loading

0 comments on commit 33a3c6f

Please sign in to comment.