how to change order of graphics and layers

1204
0
12-18-2019 09:55 AM
RudySanchez
New Contributor

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)
              })
            }
          })
        })
      })
  }
0 Kudos
0 Replies