I am moving over from leaflet to Esri and having an issue with a couple of things. Here is the result of my current attempt to place data on the map.
The issue is the polylines are above the markers. I have used the reorder function correctly for my Corelogic parcel layer but I am still trying to understand how It will apply here when the polylines are in the view instead of the map. I have an array I looping through to display the individual trips. Each node contains data for the polyline, start and finish points and collection of points (0-N).
{_multiTrips.map((item, index) => (<TripsLayer {...this.props} key={index} item={item} />))}
const Trips = (props) => {
useEffect(() => {
loadModules(['esri/layers/FeatureLayer', 'esri/geometry/Polyline', 'esri/symbols/SimpleLineSymbol', 'esri/Graphic'])
.then(([FeatureLayer, Polyline, SimpleLineSymbol, Graphic]) => {
const _startPoint = {
attributes: {id: 50000, statusText: `Start Survey`, date: props.item.groups.start.date},
geometry: {type: 'point', x: props.item.groups.start.longitude, y: props.item.groups.start.latitude}
}
const _finishPoint = {
attributes: {id: 50001, statusText: 'End Survey', date: props.item.groups.finish.date},
geometry: {type: 'point', x: props.item.groups.finish.longitude, y: props.item.groups.finish.latitude}
}
props.item.groups.tripSubFeatures.push(_startPoint)
props.item.groups.tripSubFeatures.push(_finishPoint)
const _polylineGraphic = new Graphic({
title: props.item.trip.tripName,
geometry: new Polyline({paths: props.item.locations}),
symbol: new SimpleLineSymbol({
color: props.item.trip.color,
width: 3
})
})
const _tripSubFeatures = new FeatureLayer({
title: props.item.trip.tripName,
source: props.item.groups.tripSubFeatures,
objectIdField: 'id',
fields: config.TRIP_SUBS_LAYER.fields,
popupTemplate: config.POPUP_TEMPLATE,
renderer: config.TRIP_SUBS_LAYER.renderer
})
props.view.graphics.add(_polylineGraphic)
if (props.item.groups.tripSubFeatures.length > 0) props.map.add(_tripSubFeatures)
props.polylineFeatures.push(_polylineGraphic)
props.tripSubFeatures.push(_tripSubFeatures)
props.setTripSubFeatures(props.tripSubFeatures)
props.setTripPolylineFeatures(props.polylineFeatures)
}).catch((err) => console.error(err))
return function cleanup () {
props.map.removeAll()
}
}, [])
return null
}
export default Trips
Now I had another issue of removing the polyline along with the markers when I would switch the layer off via the layer list. I found a workaround to find the correct graphics layer and add/remove it. Although it works fine I am not sure if it is the correct way of handling this. Is it not possible to have the graphics and map layers together as some type of collection? I am open to suggestions on how to set this up. But the current issue is I need the polylines to be underneath the markers.
_onMapLoad = (map, view) => {
this.setState({ map, view })
this.props.setTimeout(() => {
const _coreLogicLayer = this.props.coreLogicLayer
if (view.zoom >= 16) map.add(_coreLogicLayer)
}, 2000)
view.on('mouse-wheel', () => {
const _coreLogicLayer = this.props.coreLogicLayer
const _layer = map.layers.items.find(x => x.title === 'Core Logic')
if (view.zoom >= 16 && !_layer) {
map.add(_coreLogicLayer)
const _layer0 = map.layers.items.find(x => x.title === 'Core Logic')
map.reorder(_layer0, 0)
} else if (view.zoom < 16 && _layer) map.remove(_coreLogicLayer)
})
view.on('click', e => {
view.hitTest(e).then(resp => {
const _graphic = resp.results[0].graphic
if (_graphic && _graphic.layer.title === 'Points of Interest') this._onTogglePOI(_graphic.attributes.name)
})
})
const _this = this
const _watcherMap = this.state.map
loadModules(['esri/core/watchUtils'])
.then(([watchUtils]) => {
function watchLayerVisibility (lyr) {
const _watcher = watchUtils.watch(lyr, 'visible', e => {
const _polyline = _this.props.polylineFeatures.find(x => x.title === lyr.title)
if (!e) _this.state.view.graphics.remove(_polyline)
else _this.state.view.graphics.add(_polyline)
})
_watcherMap.set(lyr, _watcher)
}
this.state.map.allLayers.on('change', () => {
this.state.map.layers.forEach(lyr => watchLayerVisibility(lyr))
this.state.map.layers.on('changes', e => {
if (e.added.length > 0) e.added.forEach(lyr => watchLayerVisibility(lyr))
if (e.removed.length > 0) {
e.removed.forEach(lyr => {
_watcherMap.get(lyr).remove()
_watcherMap.delete(lyr)
})
}
})
})
})
}