custom widget interactions with LayerList widget

414
6
Jump to solution
03-12-2021 10:55 AM
windmilling
New Contributor II

My custom widget allows the user to add WebTiledLayer(s) to the WAB (developer 2.19) built app map https://mylaptop:3346/webappbuilder/apps/5/. I found out by accident that the ootb LayerList widget recognized the id I assigned to the WebTiledLayer(s) and displays my added layer along with the other layers from the associated webmap. I believe this behavior is what I desire for a future step.

Before the future step, I have started the next step for my custom widget - adding a graphics layer by user choice. I would like the LayerList widget to display the added graphics layer in the same manner it displays the added WebTiledLayer, but it does not. I get the added graphics layer to display as expected on the app map, and to my eyes I assign the id to the graphics layer the same as I assign the id to the WebTiledLayer(s), but the LayerList widget is not picking up the added graphics layer the way it is picking up the added WebTiled. My first suspicion is a timing thing, but I am new to this world and I don't have an idea on to start tracking that down --- I handle the Deferred the same way for both layer types. Check that --- my first suspicion is I am being dense about some simple thing.

or perhaps the issue lies with the constructor line?

const obsLayer = new GraphicsLayer({"id": myunique}); This line with the actual myunique is repeated insitu in the last code snippet.

With regard to the code snippets below, I am still learning dojo ways of doing things --- I realize my approaches with buttons is inconsistent  (I hope that isn't my the issue).

 

      startup: function() {
        this.inherited(arguments);


// The GraphicsLayer displays on the app map as expected, but is not recognized by the LayerList widget. Viewed through the console, the id seems ok in the GraphicsLayer object (similar to [not identical to] the id with the WebTiled). 
        on(this.rmButton, "click",
          lang.hitch(this, function(){
            this.gl_created().then(lang.hitch(this, function(result){
              this.map.addLayer(result);
//              console.log(result);
            }))
        }));

 

 

//WebTiled layer id is recognized by the LayerList widget
        loadButton = new Button({
          label: "Load Layer",
          disabled: true,
          onClick: lang.hitch(this, function(){
            this.getClearAg().then(lang.hitch(this, function(result){
                this.map.addLayer(result);
//                console.log(result);
              }))
          })
        }, "ChangeMap").startup();

 

// The WebTiledLayer creation part of the getClearAg function
        function requestSucceeded(result){
          var clagTile = result['display_intervals']['0']['layers'][clagDomain][clagLayer]['tile_url'];
          var URLclagTile = `${clagTile}{level}/{col}/{row}.png?${clagIDKey}`;
          var esriClag = new WebTiledLayer(URLclagTile,{"opacity": 0.8, "id": `${clagUnixSeconds}.${clagDomain}.${clagLayer}`});
          def.resolve(esriClag);         
        }

 

      gl_created: function(){
        var def = new Deferred;   
        const arrayASOS = ['KOMA','KDSM','KBMI'];
        let userInDate = this.clagDate.get("value");//user input date which is always the 00 hour local time with respect to browser
        userInDate.setUTCHours(dojo.byId('clagTODinHH').value);//user input UTC time HH is the clagTODinHH value - the userInDate object hours property is changed from 00 to the user selected HH
        let clagUnixSeconds = userInDate.getTime()/1000;//getTime returns milliseconds since jan 1 1970 but ClearAg display_time, current_time etc are in seconds


        const obsLayer = new GraphicsLayer(
          {"id": `${clagUnixSeconds}.${this.domainSelect.get("value")}.govWX.${this.paramSelect.get("value")}`}
          );
        
        for (var i=0, len = arrayASOS.length; i < len; i++){ 
          this.govWXapi(arrayASOS[i]).then(lang.hitch(this, function(result){
            obsLayer.add(result);
          }))
        }
      
        def.resolve(obsLayer);
        return def;
      },
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

By default the LayerList widget does not so GrahicsLayers. If you want your layer to appear in the layer list widget then switch to a FeatureLayer using a FeatureCollection.

https://developers.arcgis.com/javascript/3/jsapi/featurelayer-amd.html#featurelayer2

 

View solution in original post

0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

By default the LayerList widget does not so GrahicsLayers. If you want your layer to appear in the layer list widget then switch to a FeatureLayer using a FeatureCollection.

https://developers.arcgis.com/javascript/3/jsapi/featurelayer-amd.html#featurelayer2

 

View solution in original post

0 Kudos
windmilling
New Contributor II

It is an honor to interact with you Robert! With your widespread help to this community, you have indirectly held my hand on most of my steps to this point --- Thanks so Much!! btw my name is Darren. I admit I didn't before, but now I think I see the path for building the FeatureLayer I desire. I see how building the FeatureLayer on my own can be a good exercise for me, but I am wondering if you, or someone, would be able to address a few additional questions. I don't mind the work I see for the path I have in mind, but I also wouldn't mind taking an existing shortcut if someone could point it out without much effort.

The data source json (see screenshot example below) I am using has type: "FeatureCollection". Can this be compatible with arcgis FeatureCollection? To my untrained eye, the geometryType from arcgis does not match up with the api geometry? I got to the api latitude longitude coordinates with my graphic approach, but the geometry jargon this api uses I admit I have not studied.

"geometry": {
"@id": "s:GeoCoordinates",
"@type": "geo:wktLiteral"
},

and later (the api "Point" structure is not directly compatible with arcgis Point?)

"features": [
{
"id": "https://api.weather.gov/stations/KDSM/observations/2021-03-16T16:14:00+00:00",
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-93.65,
41.53
]
},

Not all choices, but the link to the screenshot example    https://api.weather.gov/stations/KDSM/observations

I am aware other sources have current weather observations (I have recently explored the ESRI Public Safety as an example), but I am interested in the short term archive with this source.

windmilling_0-1615912745091.png

 

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Darren,

  Glad to help.

  • Can this be compatible with ArcGIS FeatureCollection?  No
  • I got to the api latitude longitude coordinates with my graphic approach. Good continue to use that but add the Point geometry to your graphics and the graphics to the FeatureLayer instead of GraphicsLayer. You can see an example of how to do this in this sample https://developers.arcgis.com/javascript/3/jssamples/fl_featureCollection.html
0 Kudos
windmilling
New Contributor II

Thanks for the example. It seems straight-forward. I cannot get a display to the map however. I started with textSymbol and since I am not trying to pull from an attribute, I don't think this is the issue. I tried other simple symbols. To my capability, I boiled down the example to display a single hard coded lon,lat point, but I can't put my finger on why I can't get an expected display. In advance, Thanks for the patience on what I am guessing is a trivial matter. No console errors. Before when I have guessed about the solution direction, I have not been in the ballpark, so I will just throw out the chunk of code.

        startup: function() {
          this.inherited(arguments);
          on(this.loadButton, "click",
            lang.hitch(this, function(){

              var featureLayer;

              var featureCollection = {
                "layerDefinition": null,
                "featureSet": {
                  "features": [],
                  "geometryType": "esriGeometryPoint"
                }
              };
              featureCollection.layerDefinition = {
                "geometryType": "esriGeometryPoint",
                "objectIdField": "ObjectID",
                "drawingInfo": {
                  "renderer": {
                    "type": "simple",
                    "symbol": {
                      "type": "text",
                      "text": "22",
                      "color": "black"
                    }
                  }
                },
                "fields": [{
                  "name": "ObjectID",
                  "alias": "ObjectID",
                  "type": "esriFieldTypeOID"
                }, {
                  "name": "description",
                  "alias": "Description",
                  "type": "esriFieldTypeString"
                }, {
                  "name": "title",
                  "alias": "Title",
                  "type": "esriFieldTypeString"
                }]
              };
      
              //define a popup template
              var popupTemplate = new PopupTemplate({
                title: "{title}",
                description: "{description}"
              });
      
              //create a feature layer based on the feature collection
              featureLayer = new FeatureLayer(featureCollection, {
                id: 'flickrLayer',
                infoTemplate: popupTemplate
              });

              var features = [];
              var attr = {};
              attr["description"] = "placeHolderDescription";
              attr["title"] = "placeHolderTitle";

              var textSymbol = {
                type: "text",  // autocasts as new TextSymbol()
                color: "black",
                haloColor: "black",
                haloSize: "1px",
                text: "22",
                font: {  // autocasts as new Font()
                  size: 12,
                  family: "Josefin Slab",
                  weight: "bold"
                }
              };
//              var geometry = new Point("-93.7","41.7");
              var geometry = new Point(-93.7,41.7);
    
              var graphic = new Graphic(geometry, textSymbol);
              graphic.setAttributes(attr);

              features.push(graphic);

              featureLayer.applyEdits(features, null, null);

              this.map.addLayers([featureLayer]);
            })
          )
        }

 

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Darren,

   Couple of things to check. Open the layer list widget and see if your layer is being added. Normally I would add the layer to the map right after I have the new FeatureLayer line. 

0 Kudos
windmilling
New Contributor II

The LayerList widget does display the layer per the assigned id --- flickrLayer. The legend symbol for flickrLayer is a white circle with a black outline.

0 Kudos