Cannot clear layer with feature reduction when app is run in mobile

506
2
08-05-2021 10:23 AM
FranklinAlexander
Occasional Contributor III

I am wandering if feature reduction works on mobile devices. When I run my application in Chrome's mobile emulator and load a layer with feature reduction, it loads ok. When I try and clear the layer, however, I get this error:

clusterIssue.png

This doesn't appear to be coming from my code, I commented out everything accept for just simply loading the layer with feature reduction enabled and I still get an error.  If I test on my phone the same thing happens, the layer won't clear. This only happens with layers that have feature reduction enabled. 

 

 

mo._addBoatRampLayer = function() {
        if(window.extChange) {
          window.extChange.remove();
        }
        let url = 'https://mydomain/arcgis/rest/services/.../MapServer/1';
        loading = document.getElementById("loading-div");
        //loading.style.display = "block";
        BoatRamps = new FeatureLayer(url, {
            id: "Boat Ramps",
            featureReduction: {
              type: "cluster",
              clusterRadius: 100,
            },
            outFields: ["WaterName", "Name", "Street", "City", "Zip", "Access", "FacType", "Status", "Hours",
                        "Fees", "RampSurf", "RampCond", "TotalLane", "ParkSurf", "Trailer", "Vehicle", "Restroom"],
            opacity: 0.60
        });

        labelLayer = new GraphicsLayer({
          id: "cluster Labels"
        })

        singleGraphics = new GraphicsLayer({
          id: "single-graphics"
        });
        map.addLayer(singleGraphics, 4);

        clustExtentLayer = new GraphicsLayer({
          id: "feature-extent-polygon"
        });
        map.addLayer(clustExtentLayer, 0);

        const clSymbol = new SimpleMarkerSymbol ({
            "color": [255, 204, 0, 150],
            "size": 16,
            "type": "esriSMS",
            "style": "esriSMSCircle",
            "outline": {
              "type": "esriSLS",
              "color": [128, 102, 0, 230],
              "style": "esriSLSSolid",
              "width": 3
            }
        });

        brSymbol = new PictureMarkerSymbol ({
          "url": "widgets/WaterbodyInfo/images/BoatRamp.png",
          "height": 22,
          "width": 22,
          "type": "esriPMS",
          "angle": 0
        })

        hlSymbol = new PictureMarkerSymbol ({
          "url": "widgets/WaterbodyInfo/images/handLaunchRamp.png",
          "height": 20,
          "width": 18,
          "type": "esriPMS",
          "angle": 0
        })

        csSymbol = new PictureMarkerSymbol ({
          "url": "widgets/WaterbodyInfo/images/closureSign.png",
          "height": 20,
          "width": 18,
          "type": "esriPMS",
          "angle": 0
        })

        feSymbol = new SimpleFillSymbol (SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol (SimpleLineSymbol.STYLE_SOLID,
          new Color([139, 204, 0, 1]), 1), new Color([247, 255, 230, 0.85]));

        const clusterLabel = new TextSymbol ({
          "type": "esriTS",
          "color": [0,0,0],
          "angle": 0,
          "verticalAlignment": "middle",
          "xoffset": 0,
          "yoffset": 0,
          "kerning": true,
          "font": {
            "family": "Arial",
            "size": 10,
            "style": "normal",
            "weight": "bold",
            "decoration": "none"
          }
        });

        if(!rampLabel) {
          rampLabel = new Tooltip ({
            id: "",
            style: "position:absolute; width: 200px; z-index:100; background-color:transparent;"
          })
          rampLabel.startup();
        }
        
        const rend = new SimpleRenderer(clSymbol);
        BoatRamps.setRenderer(rend);
        map.addLayer(BoatRamps, 2);
        
        window.extChange = map.on('extent-change', lang.hitch(this, function(evt) {
          console.log("extent change");
          if(!window.appInfo.isRunInMobile) {
            if(clustExtentLayer.graphics.length > 0) {
              clustExtentLayer.clear();
            }
            if(singleGraphics) {
              singleGraphics.clear();           
            }          
            if(labelLayer.graphics.length > 0) {
              labelLayer.clear();
            }
            if(BoatRamps) {
              console.log("adding cluster labels");
              setTimeout(function() {
                _addClusterLabels(BoatRamps, labelLayer, clusterLabel, brSymbol, singleGraphics);
              }, 50);
            }
          }                 
        }));
        
        BoatRamps.on('load', function(evt) {
          map.setExtent(BoatRamps.fullExtent, true); 
          //addMouseEvents(BoatRamps);                                 
          checkClustGraph = setInterval(function() {
              let cm = BoatRamps._clusterManager;
              if(cm) {
                const gLen = cm.container.graphics.length;
              if(gLen > 0) {
                loading.style.display = "none";
                clearInterval(checkClustGraph);
                setTimeout(function() {
                  _addClusterLabels(BoatRamps, labelLayer, clusterLabel);             
                }, 50); 
                return;
              }                                  
            } 
          }, 200);                       
        });        
    },

 

 

 

Code that is throwing the error:

 

 

_clearMapGraphics: function() {
        //console.log("clearing map graphics");
        const map = this.map;
        const gIds = this.map.graphicsLayerIds;
        const lyrIds = this.map.layerIds;
        //console.log("graphics layer ids ", gIds);
        var idArray = [];
        if (gIds.length > 0) {
          for(let i = 0; i < gIds.length; i++) {
            if (gIds[i] != "graphicsLayer1") {
              idArray.push(gIds[i]);
            }
          } 
        }       
        if(lyrIds.length > 0) {
          for(var i = 0; i < lyrIds.length; i++) {
            if (lyrIds[i] != "World_Topo_Map_6790") {
              idArray.push(lyrIds[i]);
            }                                             
          }
        }        
        array.forEach(idArray, function(gId) {
          console.log("graphics layer id to remove ", gId);
          let targetLayer = map.getLayer(gId);
          console.log("target layer ", targetLayer);
          map.removeLayer(targetLayer);  //get error only when run in mobile 
                                         //and only when trying to remove 
                                         //cluster layer
        })

 

 

Just for clarification, I removed Feature Reduction from the layer and I have no errors. Also, the error occurs whether or not I comment out the events or add the additional layers. I just need to know if there is a known issue with feature reduction and mobile devices so I don't waste a lot of time trying to troubleshoot.

0 Kudos
2 Replies
BjornSvensson
Esri Regular Contributor

@FranklinAlexander - no, there is no known issue specific to feature reduction and mobile devices.

However, make sure you're testing with an updated browser using the latest OS version of your device, and that your app is using the latest version of the API. There are some general issues when using devices/browsers/OS not supported as per https://developers.arcgis.com/javascript/latest/system-requirements/ 

0 Kudos
FranklinAlexander
Occasional Contributor III

Thanks for your suggestions. I am using the latest version of Chrome so I don't think the error is a browser issue. The problem with the error is that it prevents me from using the emulation tools to test the app on a mobile device. I can't rely on my phone because it's a few years old and has Android version 10. Not sure if I can update but will look into it. From looking at the requirements for a mobile device, you need a 'hefty' device. Also, I have more going on than just clustering, I am also adding a label layer for the cluster count and a single graphics layer whenever the extent changes, so that is a lot of processing. Not sure if there is a more efficient way to do add the labels, It would be nice if the Feature Reduction had a label property, but apparently you have to use the 4x API for that ability. 

0 Kudos