infoTemplate for both GraphicsLayers and FeatureLayers

1389
14
Jump to solution
10-10-2017 06:23 AM
TylerWaring
Occasional Contributor II

I have an ArcGIS.js 3.22 application that loads a number of FeatureLayers in a map and then constructs and loads a number of GraphicsLayers. I have a click event that runs an IdentifyTask on each of the FeatureLayers in the map. It's nice because the identify task loads feature information for overlapping layers into the infoTemplate. The user is able to click the infoTemplate's arrow and cycle through features identified across all featureLayers present at a click point.  

I would like to include graphicsLayer information into the infoTemplate along with featureLayer information so that the user may loop over all features returned by their mouse click. I want the infoTemplate to show attribute information from both the featureLayers and the graphicsLayers. 

Is this possible? Dose anyone have an idea of how this would be done? It looks like ArcGIS.js 4.5 allows you to greate feature layers from graphics using the graphicsLayer's 'source' property. Can the source property in 3.22 be used similarly?  

Thanks, Tyler  

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Tyler,

   OK, I misunderstood you to say you were already doing an identifytask on your GLs in your first post. So It sounds like you have a GL on click event that populates your InfoWindow and an IdentifyTask that that you use to call setFeatures. So You could keep your GL on click method and add the Graphic from that event to a Feature Array (do not attempt to show the info window at this point and ensure the graphic has a infoTemplate defined). Then you use the click point to do the IdentifyTask and in the task results you add those features to the Feature Array var you created earlier. Now that you have all your graphics from both your GLs and your FLs you can now show your map infoWindow using the map.infoWindow.setFeatures.

View solution in original post

0 Kudos
14 Replies
RobertScheitlin__GISP
MVP Emeritus

Tyler,

   So you populate the maps InfoWindow using the IdentifyTask deferred response right? If you include the FeatureLayers in your Identify Params along with your GLs then wouldn't that work?

0 Kudos
TylerWaring
Occasional Contributor II

Hi Robert,

I'm not sure how to do that with a GraphicsLayer.  Here's a quick rundown of how I am setting up the identifyTask for my featureLayers.  I have my identify Parameters set up like this: 

var identifyParams = new IdentifyParameters();

identifyParams.tolerance = 10;
identifyParams.returnGeometry = true;
//identifyParams.geometryPrecision = 1;
//identifyParams.layerIds = [0, 2];
identifyParams.layerOption = IdentifyParameters.LAYER_ALL;
identifyParams.width = map.width;
identifyParams.height = map.height;

I then loop over my featureLayers adding their URLs to an identifyTaskArray:

identifyTaskArr.push(new IdentifyTask(layers.url));

Lastly, I loop over the identifyTaskArray and execute the identifyTasks using the identifyParameters: 

for (var j=0;j<identifyTaskArr.length;j++){

      var deferred = identifyTaskArr.execute(identifyParams)
              .addCallback(function (response) {

                     var featureArr = [];
               for (var k=0;k<response.length;k++)
               {

                           var feature = response.feature;
                  //construct jsonTitle and jsonCOntent here based on feature attibutes

                           //setting template content here

                           var json = {title:jsonTitle ,content: jsonContent};
                            var testTemplate = new InfoTemplate(json);
                     feature.setInfoTemplate(testTemplate);
                         // Add to list
                     featureArr.push(feature);

                      }

                      return featureArr;   

               });

               deferredList.push(deferred);

}

map.infoWindow.setFeature.(deferredList);

map.infoWindow.show(event.mapPoint);         

I've never performed an identifyTask on GraphicsLayers. I'm currently using a graphicsLayer on click event to pop up my infowindow(which is sub-optimal). I quess what I'm most confused about is what URL parameter I would use to create my IdentifyTask for my graphicsLayers. I am creating my graphicsLayers on the fly from attributes and coordinates from another database. 

Thanks for your help. 


Tyler 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tyler,

   OK, I misunderstood you to say you were already doing an identifytask on your GLs in your first post. So It sounds like you have a GL on click event that populates your InfoWindow and an IdentifyTask that that you use to call setFeatures. So You could keep your GL on click method and add the Graphic from that event to a Feature Array (do not attempt to show the info window at this point and ensure the graphic has a infoTemplate defined). Then you use the click point to do the IdentifyTask and in the task results you add those features to the Feature Array var you created earlier. Now that you have all your graphics from both your GLs and your FLs you can now show your map infoWindow using the map.infoWindow.setFeatures.

0 Kudos
TylerWaring
Occasional Contributor II

Hi Robert, 

I think that I may need to do this in reverse using the map's on click event... just in case the user is not interested in information from the GraphicsLayer which will be points. Is that possible too or do you advise a different workflow?

Thanks, Tyler   

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tyler,

  What ever your process is you just need to construct a graphics array from your result of both layer types and ensure those graphics have infoTemplates and then use the infoWindow.setFeatures method.

0 Kudos
TylerWaring
Occasional Contributor II

Hi Robert, I ended up picking up creating an object array of features in the graphicsLayer's on 'click' event like so:

graphicsLayer.on("click", function(event){
      var graphicFeature = {};
      graphicFeature.geometry = event.graphic.geometry;
      graphicFeature.attributes = event.graphic.attributes;
      graphicFeature.infoTemplate = event.graphic.infoTemplate;
      graphicsLayerFeatures.push(graphicFeature);
      console.log("graphicsLayerFeatures: " + JSON.stringify(graphicsLayerFeatures));
});

graphicsLayerFeatures looks like this: 

[{"geometry":{"type":"point","x":-8767571.07357861,"y":4253201.3693682095,"spatialReference":{"wkid":102100}},"attributes":{"Type":"Water Meter Asset","Name":"Meter: 73186851","Id":"02i0x00000054jOAAQ"},"infoTemplate":{"title":"Water Meter Asset","content":"Type: ${Type} <br/>Name: ${Name} <br/><span class='link' onclick='LinkAsset(\"02i0x00000054jOAAQ\",\"Salesforce\")'>Link Asset</span>"}}]

In the featureLayer identifyTask's callback I add identify results to graphicsLayerFeatures. However, the deferred response does not appreciate this and gives the following error: 

init.js:113 TypeError: a.getLayer is not a function                       init.js:133

Am I doing anything wrong? Or is there another means for getting both featureLayers and graphics in the same infoWindow?

Thanks for you help, 


Tyler 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tyler,

   What are you sending to the map.infoWindow.setFeatures? The IndentifyTask deferred or the array of graphics?

0 Kudos
TylerWaring
Occasional Contributor II

The deferred IdentityTask. I'm not sure what map.infoWindow.setFeatures requires. I couldn't find any documentation for it. should I be sending graphics? If I send it the graphics, how should I include the IdentifyTask outputs? 

Thanks, Tyler 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

You can send an array of graphics and in your case you should be. As I mentioned earlier you need to get the identify results which are graphics and add those to your graphics array.

0 Kudos