注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

程序员驿站

淘宝店:http://shop106888457.taobao.com

 
 
 

日志

 
 

Legend for Graphics Layer  

2014-10-16 18:50:51|  分类: Javascript(ArcGi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Legend for Graphics Layer
 sarals61
Level 1
sarals61 2012-2-21 上午10:50
Hello,

I have a graphics layer with a classbreaks renderer.  The breaks are computed mathematically based on the attribute values.  How can I show a legend for this graphics layer?

Thanks.

Sara S.

Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-21 上午11:53 (回复 sarals61)
Unfortunately, the legend dijit only supports tiled, dynamic, kml and feature layers.

Can you move to using a feature layer? Here's sample that shows using the legend dijit with feature layers:  http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples/widget_legend.html


Re: Legend for Graphics Layer
 sarals61
Level 1
sarals61 2012-2-22 上午1:41 (回复 sarals61)
Derek,

Thank  you for your reply.  I unfortunately do not think I can use a feature layer.  I am getting my attributes for States from an oracle stored procedure which I put in an array.  I do a query on the States layer and put the geometry in a graphic and add the attribute data which I use for the classbreaks renderer.  I'm don't think I can add the attribute information to a feature layer from the array, can I?  If not I guess I have to build the legend with dojo?

Re: Legend for Graphics Layer
 nliu
Level 4
nliu 2012-2-22 上午5:49 (回复 sarals61)
sarals61;174516


You can create a feature layer using "featureCollection". http://help.arcgis.com/en/webapi/javascript/arcgis/demos/fl/fl_featureCollection.html

It works with Legend. Make sure all async callbacks are in right order.

Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-22 下午1:35 (回复 sarals61)
nliu's recommendation is the path you should take- create a feature layer from a feature collection and you'll be able to use that with the legend dijit.

Re: Legend for Graphics Layer
 sarals61
Level 1
sarals61 2012-2-27 上午2:35 (回复 sarals61)
Thank you swingley and Derek!

Re: Legend for Graphics Layer - another question
 sarals61
Level 1
sarals61 2012-2-27 上午8:38 (回复 sarals61)
I have created a feature layer from a feature collection as suggested.  The problem is it is really slow.  In the code below I have an array of items from an Oracle stored procedure and a feature set from a States Layer.  I add this States data to the feature collection and update the collection.  It slows down at line
featureLayer.applyEdits(features, null, null);  Is there anything I'm doing wrong, or is it just slow with 50+ updates?  Thanks!

               //Create featurelayer from feature collection
                var layerDefinition = {
                    "geometryType": "esriGeometryPolygon",
                    "objectIdField": "ObjectID",
                    "fields": [{
                        "name": "ObjectID",
                        "alias": "ObjectID",
                        "type": "esriFieldTypeOID"
                    },
                    {
                        "name": "STATE_NAME",
                        "type": "esriFieldTypeString",
                        "alias": "State Name"
                    },
                    {
                        "name": "NUMB",
                        "alias": "VALUE",
                        "type": "esriFieldTypeInteger"
                    }]
                }
                var featureCollection = {
                    layerDefinition: layerDefinition,
                    featureSet: null
                };

                var content = "<b>State Name</b>: ${STATE_NAME}" +
                      "<br><b>Value</b>: ${NUMB}";
                var infoTemplate = new esri.InfoTemplate("Attributes", content);

                featureLayer = new esri.layers.FeatureLayer(featureCollection, {
                    mode: esri.layers.FeatureLayer.MODE_SNAPSHOT, infoTemplate: infoTemplate
                });

                var features = [];
                var resultFeatures = featureSet.features;  //featureSet is 51 States with State_Name attribute
                var attrs;
                for (var j = 0, il = resultFeatures.length; j < il; j++) {
                    //Get the current feature from the featureSet.
                    var stName = resultFeatures[j].attributes["STATE_NAME"];
                    var iNumb = findPosition(stName, arrStateList);                 //arrStateList - array with State_name and NUMB attributes
                    atts = { "STATE_NAME": stName, "NUMB": parseInt(iNumb) };
                    graphic = resultFeatures[j];
                    graphic.setAttributes(atts);
                    features.push(graphic);
                }
                featureLayer.applyEdits(features, null, null);
                featureLayer.setRenderer(renderer);
                map.addLayers([featureLayer]);         
                }
            }

           function findPosition(value, dataArray) {
                var a;
                var b;
                for (var i = 0; i < dataArray.length; i++) {
                    a = dataArray[i];
                    b = a["StateName"];
                    if (value == b) {
                        return a["TheNumber"];
                    }
                }
             }
 
Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-27 上午9:20 (回复 sarals61)
How long does it take for your features to be returned to the client? 

The feature layer from feature collection sample gets data from flickr which takes roughly 1s in my testing. How long does your feature layer take to display? How slow is slow?

Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-27 上午9:36 (回复 sarals61)
If applyUpdates is your bottleneck, an alternative approach would be to add your features to your feature collection before you create the actual feature layer. Our sample doesn't do this because the data returned from flickr does not have an object id. By using applyEdits, the feature layer automatically inserts an object id.

I've modified our sample to manually populate an object id attribute when creating a feature set. The end result is the same??? you get a feature layer representing geotagged photos from flickr but the feature layer's features are specified as part of the feature collection creation rather than using applyEdits:

On JSFiddle:  http://jsfiddle.net/ynm6W/

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
<html>    
  <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9" />  
    <!--The viewport meta tag is used to improve the presentation and behavior of the  
    samples on iOS devices-->  
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>  
    <title>  
      Flickr  
    </title>  
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.7/js/dojo/dijit/themes/claro/claro.css"/>  
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.7/js/esri/dijit/css/Popup.css"/>  
    <style>  
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; } .esriScalebar{  
      padding: 20px 20px; } #map{ padding:0;}  
    </style>  
    <script type="text/javascript">  
      var dojoConfig = {  
        parseOnLoad: true  
      };  
    </script>  
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.7">  
    </script>  
    <script type="text/javascript">  
      dojo.require("dijit.layout.BorderContainer");  
      dojo.require("dijit.layout.ContentPane");  
      dojo.require("esri.map");  
      dojo.require("esri.layers.FeatureLayer");  
      dojo.require("esri.dijit.Popup");  
  
  
      var map, featureLayer;  
  
      function init() {  
        //setup the map's initial extent   
        var initExtent = new esri.geometry.Extent({"xmin":-16305479,"ymin":-635073,"xmax":5884495,"ymax":8307447,"spatialReference":{"wkid":102100}});  
  
        //create a popup to replace the map's info window  
        var popup = new esri.dijit.Popup(null, dojo.create("div"));  
        map = new esri.Map("map", {  
          extent: initExtent,  
          infoWindow: popup  
        });  
        dojo.connect(map, 'onLoad', function(theMap) {  
          //resize the map when the browser resizes  
          dojo.connect(dijit.byId('map'), 'resize', map,map.resize);  
  
          // get photos from flickr then create a feature layer  
          requestPhotos();  
        });  
  
        //Add the imagery layer to the map. View the ArcGIS Online site for services http://arcgisonline/home/search.html?t=content&f=typekeywords:service      
        var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");  
        map.addLayer(basemap);  
      }  
  
      function requestPhotos(){  
        //get geotagged photos from flickr  
        //tags=flower&tagmode=all  
        var requestHandle = esri.request({  
          url: "http://api.flickr.com/services/feeds/geo?&format=json",  
          callbackParamName: "jsoncallback",  
          load: requestSucceeded,  
          error: requestFailed  
        }, {  
          useProxy: false  
        });  
      }  
        
      function requestSucceeded(response, io) {  
        //loop through the items and add to the feature layer  
        var features = [];  
        dojo.forEach(response.items, function(item, idx) {  
          var attr = {};  
          attr["description"] = item.description;  
          attr["title"] = item.title ? item.title : "Flickr Photo";  
          attr["ObjectID"] = idx;  
  
          var geometry = esri.geometry.geographicToWebMercator(new esri.geometry.Point(item.longitude, item.latitude, map.spatialReference));  
  
          var graphic = new esri.Graphic(geometry);  
          graphic.setAttributes(attr);  
          features.push(graphic);  
        });  
  
        //create a feature collection for the flickr photos  
        var featureCollection = {  
          "layerDefinition": null,  
          "featureSet": {  
            "features": features,  
            "geometryType": "esriGeometryPoint"  
          }  
        };  
          
        featureCollection.layerDefinition = {  
          "geometryType": "esriGeometryPoint",  
          "objectIdField": "ObjectID",  
          "drawingInfo": {  
            "renderer": {  
              "type": "simple",  
              "symbol": {  
                "type": "esriPMS",  
                "url": "http://dl.dropbox.com/u/2654618/flickr.png",  
                "contentType": "image/png",  
                "width": 15,  
                "height": 15  
              }  
            }  
          },  
          "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 esri.dijit.PopupTemplate({  
          title: "{title}",  
          description:"{description}"  
        });  
  
        //create a feature layer based on the feature collection  
        featureLayer = new esri.layers.FeatureLayer(featureCollection, {  
          id: 'flickrLayer',  
          infoTemplate: popupTemplate  
        });  
  
        map.addLayer(featureLayer);  
          
        //associate the features with the popup on click  
        dojo.connect(featureLayer,"onClick",function(evt){  
           map.infoWindow.setFeatures([evt.graphic]);  
        });  
      }  
  
      function requestFailed(error) {  
        console.log('failed');  
      }  
      dojo.ready(init);  
    </script>  
  </head>  
  <body class="claro">  
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'"  
    style="width: 100%; height: 100%; margin: 0;">  
      <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"  
      style="border:1px solid #000;padding:0;">  
      </div>  
    </div>  
  </body>  
  
</html>  

Re: Legend for Graphics Layer
 sarals61
Level 1
sarals61 2012-2-28 上午2:07 (回复 sarals61)
Derek,

Thank you for your reply.  When I run the code with applyedits it takes over 10 seconds to draw and sometimes I get a message regarding a slow script running on the page.

I tried running it the way you describe, creating the featurecollection before the feature layer.  It didn't work properly, nothing displayed.  It looks like when I do it the first way I get 51 graphics, but when I create the featurecollection first, the feature layer then shows one graphic with a 51 count.  I'm using a classbreaks renderer and it doesn't have all the States graphics to draw.  I don't know why the feature layer does have 51 graphics.

               var features = [];
                var resultFeatures = featureSet.features;
                var attrs;
                for (var j = 0, il = resultFeatures.length; j < il; j++) {
                    //Get the current feature from the featureSet.
                    var stName = resultFeatures[j].attributes["STATE_NAME"];
                    var iNumb = findPosition(stName, arrStateList);
                    atts = { "STATE_NAME": stName, "NUMB": parseInt(iNumb) };
                    graphic = resultFeatures[j];
                    graphic.setAttributes(atts);
                    features.push(graphic);
                }
                //Create featurelayer from feature collection
                var layerDefinition = {
                    "geometryType": "esriGeometryPolygon",
                    "objectIdField": "ObjectID",
                    "fields": [{
                        "name": "ObjectID",
                        "alias": "ObjectID",
                        "type": "esriFieldTypeOID"
                    },
                    {
                        "name": "STATE_NAME",
                        "type": "esriFieldTypeString",
                        "alias": "State Name"
                    },
                    {
                        "name": "NUMB",
                        "alias": "VALUE",
                        "type": "esriFieldTypeInteger"
                    }]
                }
                var featureCollection = {
                    "layerDefinition": layerDefinition,
                    "featureSet": {
                        "features": features,
                        "geometryType": "esriGeometryPolygon"
                    }
                }

                var content = "<b>State Name</b>: ${STATE_NAME}" +
                      "<br><b>Value</b>: ${NUMB}";
                var infoTemplate = new esri.InfoTemplate("Attributes", content);

                featureLayer = new esri.layers.FeatureLayer(featureCollection, {
                    mode: esri.layers.FeatureLayer.MODE_SNAPSHOT, infoTemplate: infoTemplate
                });

                featureLayer.setRenderer(renderer);
                map.addLayers([featureLayer]);
喜爱 显示 0 喜欢 (0) 操作 
Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-28 上午6:11 (回复 sarals61)
Two things: 
it sounds like you're using Internet Explorer. If that's the case, be sure to generalize your features using maxAllowableOffset. This results in less JSON sent to the client and is easier for IE to use. Other browsers are less likely to have this problem.
the reason you see one feature is that your feature layer does not have an ObjectID field. 

As I said in my previous post, we don't have a sample that shows this but I posted code that shows how to do it. Here's the relevant code:

var features = [];
dojo.forEach(response.items, function (item, idx) { // idx is used as the object id
  var attr = {};
  attr["description"] = item.description;
  attr["title"] = item.title ? item.title : "Flickr Photo";
  attr["ObjectID"] = idx; // populate the feature's object id

  var geometry = esri.geometry.geographicToWebMercator(new esri.geometry.Point(item.longitude, item.latitude, map.spatialReference));

  var graphic = new esri.Graphic(geometry);
  graphic.setAttributes(attr);
  features.push(graphic);
});

Re: Legend for Graphics Layer
 sarals61
Level 1
sarals61 2012-2-29 上午1:31 (回复 sarals61)
Derek,

It's working!  Thank you!

Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-2-29 上午4:45 (回复 sarals61)
Nice, glad to help. Can you mark one of my posts as answer?

Re: Legend for Graphics Layer
 jgaa
Level 1
jgaa 2012-5-18 下午1:21 (回复 sarals61)
 swingley;174901


What would the layerInfo look like for a feature layer created from a feature collection - the layerInfo the Legend dijit expects. I am trying to use just the feature layer itself.. is this correct? Thanks!

When I forked and updated your example on jsFiddle to include a legend (see http://jsfiddle.net/ynm6W/2/), the legend content is "No legend"... so how do you/would you use the legend dijit if the FeatureLayer is based on graphics?

According to the documentation for the Legend dijit: "The legend supports the following layer types: ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer, FeatureLayer and KMLLayer." However then according to the constructor detail the layerinfos are: "A layer to add to the legend. Valid layer types are: ArcGISTiledMapServiceLayer,ArcGISDynamicMapServiceLayer." So this means the FeatureLayer must be created from one of these two map service types to use the Legend dijit and a FeatureLayer from a feature collection would not be supported?

Re: Legend for Graphics Layer
 DSwingley-esristaff
Level 4
DSwingley-esristaff 2012-5-18 下午2:08 (回复 sarals61)
Couple things...
dojo.require the legend dijit
layerInfos in the Legend constructor is an array of objects, not a single object
you were missing a closing curly brace and a comma in the Legend constructor

Try this:  http://jsfiddle.net/6R3T8/

Re: Legend for Graphics Layer
 jgaa
Level 1
jgaa 2012-5-21 上午8:08 (回复 sarals61)
Thanks Derek!  In my actual code I just needed to add the [] around the layerInfo variable and it works now.  :)

  评论这张
 
阅读(632)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017