Select to view content in your preferred language

[HELP] Create custom FeatureLayer?

3239
6
08-13-2014 01:20 AM
FelixWang
New Contributor

Hi,

 

We are considering using ArcGIS JavaScript in our Windows 8.1 modern application.

The main scenario is simple: just display some "data layers" on the map.

Seems like FeatureLayer can fulfill our requirements. We did try CSVLayer and it worked.

 

However, our data source is a Web Service that returns JSON (an OData service) so CSV is not a convenient format for us.

So naturally the questions are...

1. What is alternative for our scenario? I see there are only CSV/StreamLayer, but we need to consume JSON.

2. Do we need to create our custom FeatureLayer (in our case, probably ODataJSONLayer) ?

2. Is there any tutorial, sample or learning material regarding to create a custom FeatureLayer?

3. Does it require "big" effort to do so or it is a relatively easy task?

 

Thank!

0 Kudos
6 Replies
RiyasDeen
Regular Contributor

Hi Felix,

Creating a custom feature layer will not be necessary in your case, however it would be recommended approach if re-usability is important.

1. You can use dojo/store/JsonRest — The Dojo Toolkit - Reference Guide‌ to make a request to your web service.

2. Create a GraphicsLayer on the map graphicslayer-amd | API Reference | ArcGIS API for JavaScript

3. Set renderer on GraphicsLayer for symbology.

4. Build your geometry and attributes from the web service response (assuming the web service returns a well formatted json representation of the geometry).

5. Create Graphics and add to your graphics layergraphicslayer-amd | API Reference | ArcGIS API for JavaScript

As far as effort I would say 5 man days tops.

devcig
by
New Contributor

Hi Riyas,

Thanks for your kind reply, I'm also currently looking for this information. However, the problem our project facing is, we are using the Basic Viewer instead of the Map object (esri/map), and the basic viewer seems use the web map internally which doesn't accpet CSVLayer or any other feature layers as parameters directly. So my question is, how can we make the Basic Viewer recognize my customized feature layer?

BTW, I took a look at the code which generates the map (the createMap function in esri/arcgis/utils script), but seems the script is minimized, do you have source map for the script?

Thanks in advance.

0 Kudos
RiyasDeen
Regular Contributor

Hi Dev,

The best approach would be to add your feature layer or CSV files to a map and share the map publicly. This way everything you need comes in the map and you can use this map directly in the basic viewer.

If your requirement is something like Felix, adding custom layer to your web map then may be below approach will help. You'll have a to create a function createMyLayer and hook it up on web map create event (line 29 below)

Below code was tested in sandbox.

<!doctype html>

<html>

  <head>

    <meta charset="utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>

    <title>Web Map</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css" />

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css" />

    <style>

      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      require(["dojo/ready", "dojo/on", "dojo/dom", "dijit/registry", "dojo/dom-construct", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "esri/map", "esri/arcgis/utils", "esri/domUtils", "dojo/fx", "dojo/_base/fx", "esri/layers/GraphicsLayer", "esri/InfoTemplate", "esri/geometry/Point", "esri/symbols/SimpleMarkerSymbol", "esri/Color", "esri/graphic", "esri/SpatialReference", "dojo/dom-attr", "dojo/io/script", "dojo/_base/array"       ], function(

  ready, on, dom, registry, domConstruct, parser, BorderContainer, ContentPane, Map, arcgisUtils, domUtils, coreFx, baseFx, GraphicsLayer, InfoTemplate, Point, SimpleMarkerSymbol, Color, Graphic, SpatialReference, domAttr, ioScript, array       ) {

        ready(function() {

  initMap();

       

          function initMap() {

            var deferred = arcgisUtils.createMap(("d94dcdbe78e141c2b2d3a91d5ca8b9c9"), "mainWindow");

            deferred.then(function(response){

              var map = response.map;

             

   createMyLayer(map);

            });

          }

   function createMyLayer(map){

  var gl = new GraphicsLayer({ id: "weather" });

              map.addLayer(gl);

             

  ioScript.get({

  url: "http://openweathermap.org/data/2.1/find/city",

  content: {

  lat: 48,

  lon:2,

  cnt:20

  }

  , callbackParamName: "callback"

  , load: function (data) {

  var response = data.list;

  array.forEach(response, function (loc){

  gl.add(new Graphic(

  new Point(loc.coord.lon,loc.coord.lat, new SpatialReference({wkid:4326})),

  new SimpleMarkerSymbol().setStyle(SimpleMarkerSymbol.STYLE_SQUARE).setColor(new Color([255,0,0,0.5]))

  ,{"name": loc.name, "temp":loc.main.temp,"humidity":loc.main.humidity}

  ,new InfoTemplate("Weather","Location Name: ${name} <br/>Temperature: ${temp} <br/>Humidity:${humidity}")

  ));

  });

  }

  , error: function(error) {

  alert("errro");

  }

  });

   }

        });

      });

    </script>

  </head>

  <body class="tundra">

    <div id="mainWindow">

    </div>

  </body>

</html>

devcig
by
New Contributor


Thanks Riyas. The problem with the first solution is, the map is not from us, and we are merely trying to add custom layers on top of it. So I guess I would take you solution #2. Just to confirm, according to your code above, the response from ArcGIS online/ArcGIS server portal contains the esri/map object, so I can inject my custom layers at that point right?

0 Kudos
RiyasDeen
Regular Contributor

Yes dev,

response.map is an esri/map object and you should be able to inject the code for your custom layer in the same way as i have done.

0 Kudos
devcig
by
New Contributor

Thanks for your quick reply, Riyas. One thing I found just now was, the basic map viewer seems reads layers information from the response.ItemData.operationallayers, so to make my layers appear in the legend and layers picker, I also need add according infomation to the response.ItemData.operationallayers object...

Now I found it's not easy to generated a qualified "operational layer" object, my code is like below:

response.itemInfo.itemData.operationalLayers.push({

   id : "testLayer",

   title : "Test Layer",

   visilbility: true,

   layer : gl,

   url : "",

   opacity : 0.75

  });

It misses some properties compare with the "operational layer" object in server response, e.g. the resourceInfo propety. So there were exceptions, in debugger it shows:

   "TypeError: Unable to get property 'on' of undefined or null reference
   at k (http://js.arcgis.com/3.10/init.js:213:276)
   at _layerEvent (http://localhost/ArcGISMeshupApp/js/TableOfContents.js:223:13)
   at _setLayerEvents (http://localhost/ArcGISMeshupApp/js/TableOfContents.js:289:25)
   at _createList (http://localhost/ArcGISMeshupApp/js/TableOfContents.js:189:17)
   at _init (http://localhost/ArcGISMeshupApp/js/TableOfContents.js:352:13)
   at startup (http://localhost/ArcGISMeshupApp/js/TableOfContents.js:59:17)
   at _addLayers (http://localhost/ArcGISMeshupApp/js/main.js:399:21)
   at Anonymous function (http://localhost/ArcGISMeshupApp/js/main.js:154:25)
   at Anonymous function (http://js.arcgis.com/3.10/init.js:174:14)
   at k (http://js.arcgis.com/3.10/init.js:195:425)"

I'm not sure whether there are any official means to generate this "operational layer" object? Riyas Deen

0 Kudos