Closed ErikaHD closed 6 years ago
Don't have time for a full explainer, but here is some code that I've written. Warning: it's not the most elegant code, but the problem with leaflet & react is that react wants to manage all that is DOM, and Leaflet interferes with that.
https://github.com/murb/exons-client/blob/master/src/components/MapComponent.jsx
Note, there are some quite project specific things going on here, but maybe you can follow what is happening.
Thank you murb for your answer. I will look into it now. Did you try this library with Angular? I am thinking to use it for mobile app development.
Thanks again
Nope, not used with angular or any other (semi-)native solution
Op 18 jul. 2018 om 11:16 heeft ErikaHD notifications@github.com het volgende geschreven:
Thank you murb for your answer. I will look into it now. Did you try this library with Angular? I am thinking to use it for mobile app development.
Thanks again
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
Thank you for your help again. I really appreciate it.
@murb would I be able to take a look at the code you linked earlier? Seems the link is broken
@benjamineac this is the code at the time it was still in the open:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Leaflet from 'leaflet';
import 'leaflet.nontiledlayer';
import 'leaflet-timedimension';
class MapComponent extends Component {
constructor (props) {
super(props);
this.initializeMap = this.initializeMap.bind(this);
this.dimensionSummary = '';
}
initializeMap (props) {
if (this.currentMap) { this.currentMap.remove(); }
const { timeInterval, zoom, centerLatLon, timeDimensionControl, geovisActions, dispatch } = props;
this.currentMap = Leaflet.map('map-8d7b0efd-96bb-4b8f-8ccd-936edbeac503', {
buffer: 20,
crs: Leaflet.CRS.EPSG3857,
timeDimension: true,
timeDimensionOptions: {
timeInterval: timeInterval,
period: 'PT5M'
},
timeDimensionControlOptions: {
position: 'bottomleft',
playerOptions: {
minBufferReady: 4,
transitionTime: 500
}
},
timeDimensionControl: timeDimensionControl
}).setView(centerLatLon, zoom);
Leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(this.currentMap);
this.currentMapLayers = Leaflet.layerGroup();
this.currentMapLayers.addTo(this.currentMap);
this.currentMapHotSpotLayers = Leaflet.layerGroup();
this.currentMapHotSpotLayers.addTo(this.currentMap);
this.currentLinesLayers = Leaflet.layerGroup();
this.currentLinesLayers.addTo(this.currentMap);
window.leafletMap = this.currentMap;
}
componentDidMount () {
this.componentWillUpdate(this.props);
}
componentWillUpdate (nextProps) {
const { layers, hotSpots, geovisActions, dispatch, wmsDimensions, timeDimensionControl, focus } = nextProps;
if (
nextProps.viewName !== this.props.viewName ||
nextProps.timeDimensionControl !== this.props.timeDimensionControl ||
typeof this.currentMap === 'undefined'
) {
this.initializeMap({
timeDimensionControl: timeDimensionControl,
timeInterval: nextProps.timeInterval,
zoom: nextProps.zoom,
centerLatLon: nextProps.centerLatLon
});
this.lastUpdatedMapLayersAt = 0;
}
if (this.currentMapHotSpotLayers) this.currentMapHotSpotLayers.clearLayers();
const defaultIconOptions = {
iconUrl: '/marker-blue.png',
iconSize: [25, 43],
iconAnchor: [12, 43],
popupAnchor: [-3, -76],
shadowUrl: '/marker-shadow.png',
shadowSize: [31, 21],
shadowAnchor: [0, 21]
};
const defaultIcon = Leaflet.icon(
defaultIconOptions
);
const selectedIcon = Leaflet.icon(
Object.assign(defaultIconOptions, { iconUrl: '/marker-lightblue.png' })
);
hotSpots.forEach((hotspot) => {
const selected = focus && hotspot.dataUrl === focus.dataUrl;
const marker = Leaflet.marker(hotspot.centerLatLon, {
icon: (selected ? selectedIcon : defaultIcon), alt: hotspot.name, title: hotspot.name
});
marker.on('click', () => {
dispatch(geovisActions.setFocus(hotspot));
dispatch(geovisActions.fetchTimeseries({ url: hotspot.dataUrl }));
});
marker.addTo(this.currentMapHotSpotLayers);
});
let newDimensionSummary = '';
for (const dimension in wmsDimensions) {
newDimensionSummary = newDimensionSummary + dimension + wmsDimensions[dimension];
}
// every 5 min is ok for maplayers
const mapLayerRefreshNeeded = (new Date()).getTime() - this.lastUpdatedMapLayersAt > 1000 * 60 * 1;
if (mapLayerRefreshNeeded || newDimensionSummary !== this.dimensionSummary) {
this.lastUpdatedMapLayersAt = (new Date()).getTime();
this.dimensionSummary = newDimensionSummary;
} else {
return false;
}
if (this.currentMapLayers) this.currentMapLayers.clearLayers();
layers.forEach((layer) => {
const variableWMSLayer = layer.wmsLayer.match(/\{(.*)\}/);
const wmsLayer = (variableWMSLayer) ? layer.wmsLayer.replace(variableWMSLayer[0], wmsDimensions[variableWMSLayer[1]]) : layer.wmsLayer;
let layerOptions = {
layers: wmsLayer,
styles: layer.styles,
format: 'image/png',
opacity: (layer.opacity ? layer.opacity : 1),
transparent: true,
tileSize: 1500,
updateWhenIdle: false,
updateWhenZooming: false,
updateInterval: 600
};
for (const dimension in wmsDimensions) {
layerOptions[`DIM_${dimension}`] = wmsDimensions[dimension];
}
const llayer = (layer.timeLayer) ? Leaflet.timeDimension.layer.wms(Leaflet.tileLayer.wms(layer.wms, layerOptions)) : Leaflet.nonTiledLayer.wms(layer.wms, layerOptions);
llayer.addTo(this.currentMapLayers);
});
dispatch(geovisActions.fetchMapMetaData(layers[0], nextProps.focusLatLon, wmsDimensions));
}
render () {
return (
<div id='map-8d7b0efd-96bb-4b8f-8ccd-936edbeac503' className='leaflet-map' />
);
}
}
MapComponent.propTypes = {
viewName: PropTypes.string,
timeDimensionControl: PropTypes.bool,
geovisActions: PropTypes.object,
dispatch: PropTypes.func
};
export default MapComponent;
Hi, Has anyone try to use Leaflet.TimeDimension with React? I will really appreciate any help on how to do this. Thank you :-)