FeatureLayer from JSON

652
1
02-11-2019 03:07 AM
PaulBargewell
New Contributor

I'm very new to Esri and by no means a GIS professional either. So please forgive me if what I'm asking seems noobish.

We have a need to display an Esri map that a visitor can add a marker onto to report an incident. Before the visitor reports the incident we'd like to load all previously reported incidents onto the map so the visitor can see if their incident has been previously reported.

My plan is to have the user select an class of incident and we'd then load those incidents from a Json source into a FeatureLayer. If the user changes the incident class we'd hide that FeatureLayer and load the newly selected incident classes from json, into another FeatureLayer, etc.

I'm using Vue and have imported the esri-loader. I followed some examples of loading data from Json into a FeatureSet, but nothing appears on my map.

I can put symbols onto the data layer and that works, but I thought FeatureLayers would be the best place to put my user data.

I'd be grateful if someone could take a look at my code and advise on if the approach I'm using is even valid or where I'm making a mistake in adding to and showing the layer.

<template>
  <div id="main">
    <div
      ref="map"
      class="map"
    />
  </div>
</template>
<script>
import { loadScript, loadModules } from 'esri-loader'

// preload the ArcGIS API
const options = {
  url: '//js.arcgis.com/3.27/',
}
loadScript(options)

export default {
  data() {
    return {
      map: null,
      userLayer: null,
      Map: null,
      GraphicsLayer: null,
      Point: null,
      SimpleMarkerSymbol: null,
      Graphic: null,
      FeatureLayer: null,
      FeatureSet: null,
      SimpleRenderer: null
    }
  },
  mounted() {
    loadModules(['esri/map', 'esri/layers/GraphicsLayer', 'esri/geometry/Point',
      'esri/symbols/SimpleMarkerSymbol', 'esri/graphic', 'esri/layers/FeatureLayer',
      'esri/renderers/SimpleRenderer'])
      .then(([Map, GraphicsLayer, Point, SimpleMarkerSymbol, Graphic, FeatureLayer,
        SimpleRenderer]) => {
        this.Map = Map
        this.GraphicsLayer = GraphicsLayer
        this.Point = Point
        this.SimpleMarkerSymbol = SimpleMarkerSymbol
        this.Graphic = Graphic
        this.FeatureLayer = FeatureLayer
        this.SimpleRenderer = SimpleRenderer

        // create map with the given options
        this.map = new this.Map(this.$refs.map, {
          center: [-1.2040487, 52.7690669],
          zoom: 16,
          basemap: 'topo',
        })

        this.map.on('load', () => {
          let renderer = new SimpleRenderer({
            symbol: this.markerSymbol([0, 255, 0, 255])
          })

          let fields = [
            {
              name: 'ObjectId',
              alias: 'ObjectId',
              type: 'number'
            }, {
              name: 'lat',
              alias: 'lat',
              type: 'number'
            }, {
              name: 'lng',
              alias: 'lng',
              type: 'number'
            }
          ]

          let data = [
            {
              lat: -1.1260934,
              lng: 52.6670721
            },
            {
              lat: -1.17365,
              lng: 52.7515022
            }
          ]

          let points = data.map((point, idx) => {
            return {
              geometry: new Point({
                x: point.lng,
                y: point.lat
              }),
              attributes: {
                ObjectId: idx,
                lat: point.lat,
                lng: point.lng
              }
            }
          })

          let featureCollection = {
            layerDefinition: {
              geometryType: 'esriGeometryPoint',
              fields: fields,
              spatialReference: {
                wkid: 4326
              },
            },
            featureSet: points
          }

          this.userLayer = new this.FeatureLayer(featureCollection, {
            supportsEditting: true,
            supportsAdd: true,
            source: points,
            renderer: renderer,
            fields: fields,
            objectIdField: 'ObjectId',
            geometryType: 'esriGeometryPoint'
          })

          this.userLayer.setRenderer(renderer)

          this.map.addLayer(this.userLayer)

        })
      })
      .catch(err => {
        console.error(err) // eslint-disable-line no-console
      })
  },
  methods: {
    markerSymbol(color) {
      let markerSymbol = new this.SimpleMarkerSymbol({
        color: color,
        size: 60,
        angle: 0,
        xoffset: 0,
        yoffset: 30,
        outline: {
          color: [0, 0, 0, 255],
          width: 5,
          type: 'esriSLS',
          style: 'esriSLSSolid'
        }
      })
      markerSymbol.setPath('M256,0C167.641,0,96,71.625,96,160c0,24.75,5.625,48.219,15.672,69.125C112.234,230.313,256,512,256,512l142.594-279.375   C409.719,210.844,416,186.156,416,160C416,71.625,344.375,0,256,0z M256,256c-53.016,0-96-43-96-96s42.984-96,96-96   c53,0,96,43,96,96S309,256,256,256z')
      return markerSymbol
    }
  }
}
</script>
<style>
@import url('//js.arcgis.com/3.27/esri/css/esri.css');

.map {
  height: 500px;
}
</style>

If I write direct to the graphics layer with the following I can get markers displayed:

      let points = [[-1.1260934, 52.6670721], [-1.17365, 52.7515022]]
      points.forEach(point => {
        let graphic = new this.Graphic(new this.Point(point), this.markerSymbol([255, 0, 0, 128]))
        this.map.graphics.add(graphic)
      })

Thanks

0 Kudos
1 Reply
PaulBargewell
New Contributor

I think I have resolved this following on from a response to 171775

By creating a FeatureSet from json I 'm able to build the layer and add it successfully.

<template>
  <div id="main">
    <div
      ref="map"
      class="map"
    />
  </div>
</template>
<script>
import {
  loadScript,
  loadModules
} from 'esri-loader'

// preload the ArcGIS API
const options = {
  url: '//js.arcgis.com/3.27/',
}
loadScript(options)

export default {
  data() {
    return {
      map: null,
      userLayer: null,
      Map: null,
      GraphicsLayer: null,
      Point: null,
      SimpleMarkerSymbol: null,
      Graphic: null,
      FeatureLayer: null,
      FeatureSet: null,
      SimpleRenderer: null,
      Color: null
    }
  },
  mounted() {
    loadModules(['esri/map', 'esri/layers/GraphicsLayer', 'esri/geometry/Point',
      'esri/symbols/SimpleMarkerSymbol', 'esri/graphic', 'esri/layers/FeatureLayer',
      'esri/tasks/FeatureSet', 'esri/renderers/SimpleRenderer', 'esri/Color'
    ])
      .then(([Map, GraphicsLayer, Point, SimpleMarkerSymbol, Graphic, FeatureLayer,
        FeatureSet, SimpleRenderer, Color
      ]) => {
        this.Map = Map
        this.GraphicsLayer = GraphicsLayer
        this.Point = Point
        this.SimpleMarkerSymbol = SimpleMarkerSymbol
        this.Graphic = Graphic
        this.FeatureLayer = FeatureLayer
        this.FeatureSet = FeatureSet
        this.SimpleRenderer = SimpleRenderer
        this.Color = Color

        let map = new Map(this.$refs.map, {
          center: [-1.2040487, 52.7690669],
          basemap: 'topo',
          zoom: 17
        })

        map.on('load', () => {

          let data = [
            {
              lng: -1.2040487,
              lat: 52.7690669
            }, {
              lng: -1.1260934,
              lat: 52.6670721
            }, {
              lng: -1.17365,
              lat: 52.7515022
            }
          ]

          let features = data.map((point, idx) => {
            return {
              geometry: new Point({
                x: point.lng,
                y: point.lat
              }, {
                spatialReference: {
                  wkid: 4326
                }
              }),

              attributes: {
                Name: `ObjectId${idx+1}`,
                OBJECTID: idx + 1
              }
            }
          })

          var jsonFS = {
            geometryType: 'esriGeometryPoint',
            features: features,
            spatialReference: {
              wkid: 4326
            }
          }

          var featureSet = new FeatureSet(jsonFS)

          var layerDefinition = {
            displayFieldName: 'Name',
            geometryType: 'esriGeometryPoint',
            spatialReference: {
              wkid: 4326
            },
            fields: [{
              name: 'OBJECTID',
              type: 'esriFieldTypeOID',
              alias: 'OBJECTID'
            }, {
              name: 'Name',
              type: 'esriFieldTypeString',
              alias: 'Name',
              length: 10
            }]
          }

          var featureCollection = {
            layerDefinition: layerDefinition,
            featureSet: featureSet
          }

          let featureLayer = new FeatureLayer(featureCollection)
          // let symbol = new SimpleMarkerSymbol().setColor(new Color([255, 0, 0, 0.5]))
          let renderer = new SimpleRenderer(this.markerSymbol([0, 255, 0, 0.5]).setColor([0, 255, 0, 0.5]))
          featureLayer.setRenderer(renderer)

          map.addLayer(featureLayer)
        })

      })
      .catch(err => {
        console.error(err) // eslint-disable-line no-console
      })
  },
  methods: {
    markerSymbol(color) {
      let markerSymbol = new this.SimpleMarkerSymbol({
        color: color,
        size: 60,
        angle: 0,
        xoffset: 0,
        yoffset: 30,
        outline: {
          color: [0, 0, 0, 255],
          width: 5,
          type: 'esriSLS',
          style: 'esriSLSSolid'
        }
      })
      markerSymbol.setPath(
        'M256,0C167.641,0,96,71.625,96,160c0,24.75,5.625,48.219,15.672,69.125C112.234,230.313,256,512,256,512l142.594-279.375   C409.719,210.844,416,186.156,416,160C416,71.625,344.375,0,256,0z M256,256c-53.016,0-96-43-96-96s42.984-96,96-96   c53,0,96,43,96,96S309,256,256,256z'
      )
      return markerSymbol
    }
  }
}
</script>
<style>
@import url('//js.arcgis.com/3.27/esri/css/esri.css');

.map {
  height: 500px;
}
</style>
0 Kudos