Select to view content in your preferred language

Creating a customisable buffer around points in a feature layer - Javascript API

3612
7
Jump to solution
05-23-2012 04:35 AM
RossPudney
Emerging Contributor
Hi,

I am sorry if this has been posted before - but I have searched the forums before posting and haven't come across anything so my apologies if there is a solution already. I am new to Javascript and am trying to put together a web page which enables me to do the following:


  • Show layers from my ArcGIS Server

  • Enable the user to draw a buffer around the point level feature layer I have in my map (and be able to determine the size of the buffer)

  • Do a query on another polygon layer I have from my Server which intersects with the buffer and provides a sum of the values in a given field column

I am only interested at this stage in finding out how to do the second point and wondered if anyone could help me? I have copy/pasted the ArcGIS resources code for creating a buffer on a click event and inserted into my code below.


The steps I need to understand are:

- How do I make the script draw the buffer around my point layer (it is named asa variable 'Lyr_StrokeUnits') ?

- How do I make the script draw the buffers without the 'onClick' event and instead to draw the buffers dependent on a user input? (Ideally I want the user to be able to input the buffer radius value as they can now and then to be able to press a button to redraw the buffers for all points)


I would be very grateful for any help anyone could give me on this issue.


Kind regards,

Ross



The relevant code below:


function initFunctionality(map) {


        //Identify proxy page to use if the toJson payload to the geometry service is greater than 2000 characters.
        //If this null or not available the buffer operation will not work.  Otherwise it will do a http post to the proxy.
        esri.config.defaults.io.proxyUrl = "/arcgisserver/apis/javascript/proxy/proxy.ashx";
        esri.config.defaults.io.alwaysUseProxy = false;


        //Geometry Service Endpoint
        var gsvc = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        //Listens for an onClick event in the map
        dojo.connect(map, "onClick", function(evt) {
          map.graphics.clear();
          var params = new esri.tasks.BufferParameters();
          params.geometries  = [ evt.mapPoint) ];

          //Sets the parameters for the buffer in miles and creates the buffer in code, but DOESNT display it
          params.distances = [ dojo.byId('bufferDistance').value ]; //'bufferDistance' is a variable which the user inputs on the main page - found in body code
          params.unit = esri.tasks.GeometryService.UNIT_STATUTE_MILE; // standard miles
          params.bufferSpatialReference = new esri.SpatialReference({wkid: 3857}); //Sets the SRID for the buffer
          params.outSpatialReference = map.spatialReference; //Sets the SRID for the output of the buffer service
          gsvc.buffer(params);
          dojo.byId('messages').innerHTML = "<b>Creating Buffer</b>";
        });

        //Listens for GeometryService onBufferComplete event and then draws the buffer onto the map
        dojo.connect(gsvc, "onBufferComplete", function(geometries) { //gsvc is the centrepoint location where the initial click is recorded
          var symbol = new esri.symbol.SimpleFillSymbol("none", new esri.symbol.SimpleLineSymbol("solid", new dojo.Color([255,0,0]), 2), new dojo.Color([255,255,0,0.25])); // creates the buffer symbol
          var graphic = new esri.Graphic(geometries[0],symbol); //creates the buffer graphic which is actually displayed onto the map
          map.graphics.add(graphic); //Adds the buffer to the map
          dojo.byId('messages').innerHTML = "<b>Draw Buffer Complete.</b>";
        });

     }
0 Kudos
1 Solution

Accepted Solutions
derekswingley1
Deactivated User
Remove the "var" from in front of Lyr_StrokeUnit when you create your feature layer in the init function. Removing var will keep Lyr_StrokeUnit as a global. When you use var inside a function, you create a local variable. Because Lyr_StrokeUnit is local to init, that feature layer is not accessible in the drawBuffer function via the Lyr_StrokeUnit variable.

View solution in original post

0 Kudos
7 Replies
RossPudney
Emerging Contributor
If anyone is able to help me with this I would be so grateful.
0 Kudos
derekswingley1
Deactivated User
Take the geometries from your feature layer and specify them as your params.geometries. Something like this:
// dojo.map returns an array 
// fl is your feature layer
var geoms = dojo.map(fl.graphics, function(g) {
  return g.geometry;
});
params.geometries = geoms
0 Kudos
RossPudney
Emerging Contributor
Take the geometries from your feature layer and specify them as your params.geometries. Something like this:
// dojo.map returns an array 
// fl is your feature layer
var geoms = dojo.map(fl.graphics, function(g) {
  return g.geometry;
});
params.geometries = geoms



Thank you Derek - unfortunately that hasn't worked. I have however been editing my code since I posted this afternoon based on other examples and forum questions which seemed to have similar issues. I have removed the actual address to the data I am using from my server as I can't disclose it I am afraid, so I do apologise about that.


I have included it below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!-- The HEAD section is the section of code which references and loads all scripts before it is shown on the webpage -->
  <head>
    <title>XXX</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/dojo/dijit/themes/nihilo/nihilo.css">
 <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/esri/dijit/css/Popup.css"/>

 <!--Script 1 loads the Javascript API files -->
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script>
    <!--Script 2 is where all the code written is executed -->
 <script type="text/javascript">
      
   //The code script is split into three sections;
   //(1) Reference of a package: Packages are bundles of resources which enable features to work. For adding maps for example
   // the dojo (the underlying basis for Javascript) needs to pull in the 'map' package, hence dojo.require("esri.map") which
   // enables the browser to work with maps
   
   //(2) Initialisation function(s): The initialisation function(s) are in essence a loading function which adds layers to the map and executes
   // a range of code / processes. As layers can't be physically added, they are pulled from a webservice where appropriate.
   
   //(3) Script Load: This function runs the specified script, but ensures that the script only runs once the HTML webpage is loaded. This
   // is important as it stops the scripts running BEFORE the map baselayer is loaded.
   
   
   
 //(1) Packages import
   // .require is basically an 'include' function which brings in the resources to display maps
   dojo.require("esri.map"); // creates the map class for all elements to be loaded into
   dojo.require("esri.tasks.query"); // retrieves features from a map layer based on geography or attribute conditions.
      dojo.require("esri.tasks.geometry"); //gives you access to an ArcGIS Server geometry service that can buffer, project, and simplify geometries
   dojo.require("esri.layers.FeatureLayer"); //enables loading of feature layers  
   

   //Pre-load the variables to be used in the script - saves time and memory in terms of processing   
   //Base Variables
   var map
   var BaseMap
   
   //Layer Variables
   var Lyr_StrokeUnits
   var Lyr_UKPopData
   
   //Task Variables
   var queryTask
   var gsvc
   
   
 //(2) Initialisation functions
 //(2.1) Creates a function called init which adds the base map and feature layers used in the map

 function init() {
  
  //Set the map extent and spatial reference
  var ExtentAndSR = new esri.geometry.Extent(-65000,6000000,-800000,8700000,new esri.SpatialReference({"wkid":3857}));
  
  //Creates the Map container / object
  var map = new esri.Map("map",{extent:ExtentAndSR});

    //Defines what the variable 'map' does. In this case, it is defined as a Map Class (esri.map)
    //and the 'map' segment provides it with a reference to be displayed in the webpage (ie: The DIV
    //is an object visible in the webpage. As map pulls map data, it is then 'translated' to the DIV
    //element so that it can be shown on the map


  //Listens for when the Map Container is loaded and then adds query functionality in a seperate function after the init script
        dojo.connect(map, "onLoad", initFunctionality);  

  
  //Basemap
  //The underlying raster basemap used in the web portal
  
   var BaseMap = new //This line and the next defines the variable 'BaseMap' and what basemap will be used
   esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"); //Creates the reference for the variable (ie: where it is coming from)
   map.addLayer(BaseMap); //This adds this layer to the 'base' layer of "map"

  
  //Layers
  //Layers are loaded in succession - the last layer will be the 'top' layer and so on:
  
   //Lyr_UKPopData
   var Lyr_UKPopData = new
   esri.layers.FeatureLayer("xxx", {
   mode : esri.layers.FeatureLayer.MODE_ONDEMAND});
   map.addLayer(Lyr_UKPopData);  
   
   //Lyr_StrokeUnits
   var Lyr_StrokeUnits = new
   esri.layers.FeatureLayer("xxx", {
   mode : esri.layers.FeatureLayer.MODE_ONDEMAND});
   map.addLayer(Lyr_StrokeUnits); 
  
 
  }
  
  
 //(2.2) Creates a function called initFunctionality(map) which contains the querying scripts for buffer analysis
 
     function initFunctionality(map) {

        //Geometry Service Endpoint
        var gsvc = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
    }
 
 
        function drawBuffer() {
          var buffParams = new esri.tasks.BufferParameters();
    var flgeom = dojo.map(Lyr_StrokeUnits.graphics, function(g) {
    return g.geometry;
    });    
          buffParams.geometries = flgeom; 
          buffParams.distances = [dojo.byId('bufferDistance').value];
          buffParams.unit = esri.tasks.GeometryService.UNIT_STATUTE_MILE;
          buffParams.bufferSpatialReference = new esri.SpatialReference({wkid:3857});
          buffParams.outSpatialReference = map.spatialReference;
          gsvc.buffer(buffParams, bufferDraw);

          
    var bufferDraw = dojo.connect(gsvc, "onBufferComplete", function (geometries) {
          var symbol = new esri.symbol.SimpleFillSymbol("none", new esri.symbol.SimpleLineSymbol("solid", new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]));
    var graphic = new esri.Graphic(geometries[0], symbol);
          map.graphics.add(graphic);
   
          });
   
  } 

 
 //(3) Script Load
  dojo.addOnLoad(init);
   
    </script>
  </head>
  
 <!-- The BODY section which determines the style and positioning of elements in the webpage -->
 <body>
 <body class="nihilo">
 TEST<br>
    Buffer distance (Miles): <input type="text" id="bufferDistance" value="10" size="5"/><input type='button' value='Draw Buffer' onclick='drawBuffer()'/><br>
 <div id="map" style="width: 100%; height: 800px; margin: 0;"></div>
 <span id="messages"></span>
</body>
</html>


You will see that I included your variable solution into the above, and yet I haven't had any joy with it. Do I need to add another dojo.connect somewhere? Or should my 'Draw Buffer' button work?

Thank you for your help so far.

Ross
0 Kudos
RossPudney
Emerging Contributor
Is there any further help anyone could offer me on this? Again I would be immensely grateful. It seems that the issue is that my feature layer isn't supply the function with the necessary geometries - anyone know why this might be the case?
0 Kudos
derekswingley1
Deactivated User
Remove the "var" from in front of Lyr_StrokeUnit when you create your feature layer in the init function. Removing var will keep Lyr_StrokeUnit as a global. When you use var inside a function, you create a local variable. Because Lyr_StrokeUnit is local to init, that feature layer is not accessible in the drawBuffer function via the Lyr_StrokeUnit variable.
0 Kudos
RossPudney
Emerging Contributor
Thank you Derek. That, and the removal of a few extra ';' made it work. I'm very grateful. Thank you.
0 Kudos
derekswingley1
Deactivated User
Glad to help! And thanks for marking this one answered 🙂
0 Kudos