Search code examples
javascriptbufferesriarcgis-js-api

using my esri webmap to make buffer with ArcGIS API for JavaScript


I can load my esri web map but the buffer didn't work.

I used the sample from developers.arcgis.com/javascript from this path: https://developers.arcgis.com/javascript/jssamples/util_buffergraphic.html

And modified it by adding my web map id and made some changes.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--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>Buffer</title>

<link rel="stylesheet" href="http://js.arcgis.com/3.13/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
   html, body {
    height: 100%;
    width: 100%;
    margin: 0; 
    padding: 0;
    overflow:hidden;
  }
  #leftPane{
    color:#000;
    width:250px;
    padding-bottom:15px;
  }
  #map{
    padding:0;
  }
  .details{
    font-size:14px;
    font-weight:600;
    padding-bottom:20px;
  }

  button{
    margin:2px;
    cursor:pointer;
  }
</style>

<script src="http://js.arcgis.com/3.13/"></script>
<script>
var map, tb,
        webmapId = "62847ab75c1b4f7d829a530b7c4432f2";

require(["dojo/dom",

        "dojo/_base/array",
        "dojo/parser",
        "dojo/query",
        "dojo/on",

        "esri/Color",
        "esri/config",
        "esri/map",
        "esri/arcgis/utils",
        "esri/graphic",

        "esri/geometry/normalizeUtils",
        "esri/tasks/GeometryService",
        "esri/tasks/BufferParameters",
  
        "esri/toolbars/draw",
  
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dijit/form/Button", "dojo/domReady!"
        ],
      function(dom, array, parser, query, on, Color, esriConfig, Map, arcgisUtils, Graphic, normalizeUtils, GeometryService, BufferParameters, Draw, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol){

        parser.parse();


        esriConfig.defaults.geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        esriConfig.defaults.io.proxyUrl = "/proxy/";
        esriConfig.defaults.io.alwaysUseProxy = false;
  
        arcgisUtils.createMap(webmapId, "map").then(function (response) {
        map = response.map;
        });
        map.on("load", initToolbar);

       //Setup button click handlers
        on(dom.byId("clearGraphics"), "click", function(){
          if(map){
            map.graphics.clear();
          }
        });
        //click handler for the draw tool buttons
        query(".tool").on("click", function(evt){
          if(tb){
           tb.activate(evt.target.id);
          }
        });
        

      function initToolbar(evtObj) {
        tb = new Draw(evtObj.map);
        tb.on("draw-end", doBuffer);
      }

      function doBuffer(evtObj) {
        tb.deactivate();
        var geometry = evtObj.geometry, symbol;
        switch (geometry.type) {
           case "point":
             symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255,0,0]), 1), new Color([0,255,0,0.25]));
             break;
           case "polyline":
             symbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255,0,0]), 1);
             break;
           case "polygon":
             symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NONE, new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT, new Color([255,0,0]), 2), new Color([255,255,0,0.25]));
             break;
        }

          var graphic = new Graphic(geometry, symbol);
          map.graphics.add(graphic);

          //setup the buffer parameters
          var params = new BufferParameters();
          params.distances = [ dom.byId("distance").value ];
          params.outSpatialReference = map.spatialReference;
          params.unit = GeometryService[dom.byId("unit").value];
          //normalize the geometry 

          normalizeUtils.normalizeCentralMeridian([geometry]).then(function(normalizedGeometries){
            var normalizedGeometry = normalizedGeometries[0];
            if (normalizedGeometry.type === "polygon") {
              //if geometry is a polygon then simplify polygon.  This will make the user drawn polygon topologically correct.
              esriConfig.defaults.geometryService.simplify([normalizedGeometry], function(geometries) {
                params.geometries = geometries;
                esriConfig.defaults.geometryService.buffer(params, showBuffer);
              });
            } else {
              params.geometries = [normalizedGeometry];
              esriConfig.defaults.geometryService.buffer(params, showBuffer);
            }

          });
        }

        function showBuffer(bufferedGeometries) {
          var symbol = new SimpleFillSymbol(
            SimpleFillSymbol.STYLE_SOLID,
            new SimpleLineSymbol(
              SimpleLineSymbol.STYLE_SOLID,
              new Color([255,0,0,0.65]), 2
            ),
            new Color([255,0,0,0.35])
          );

          array.forEach(bufferedGeometries, function(geometry) {
            var graphic = new Graphic(geometry, symbol);
            map.graphics.add(graphic);
          });

        }
  });
</script>

</head>

<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" 
     data-dojo-props="gutters:'true', design:'sidebar'" 
     style="width:100%;height:100%;">

  <div id="map" 
       data-dojo-type="dijit/layout/ContentPane" 
       data-dojo-props="region:'center'">
  </div>

  <div id="leftPane" 
       data-dojo-type="dijit/layout/ContentPane" 
       data-dojo-props="region:'left'">
    <div class="details">Pick a tool and draw on the map. The drawn graphic will be buffered based on the specified parameters.</div>
    <button type="button" class="tool" id="line">Line</button>
    <button type="button" class="tool" id="polyline">Polyline</button>
    <button type="button" class="tool" id="freehandpolyline">Freehand Polyline</button>
    <br/>
    <button type="button" class="tool" id="polygon">Polygon</button>
    <button type="button" class="tool" id="freehandpolygon">Freehand Polygon</button>
    <br/><hr />
    <div><b>Buffer Parameters</b></div>
    Distance:&nbsp;<input type="text" id="distance" size="5" value="25" />
    <select id="unit" style="width:100px;">
      <option value="UNIT_STATUTE_MILE">Miles</option>
      <option value="UNIT_FOOT">Feet</option>
      <option value="UNIT_KILOMETER">Kilometers</option>
      <option value="UNIT_METER">Meters</option>
      <option value="UNIT_NAUTICAL_MILE">Nautical Miles</option>
      <option value="UNIT_US_NAUTICAL_MILE">US Nautical Miles</option>
      <option value="UNIT_DEGREE">Degrees</option>
    </select><br />
    <button type="button" id="clearGraphics"  type="button">Clear Graphics</button>
  </div>
</div>
</body>
</html>


Solution

  • You are using webmap and you have attached "load" event on it which is not required. Below is the detail explaination:

    1. your map object is undefined because before coming response of webmap you are calling "on" method of map. (this is not required)

    2. if you are getting "response.map" it means your map object is loaded. so need to attached event on "load"

    3. your map object is already loaded so just need to initialize your draw tool bar.

    Below is the working code:

    <!DOCTYPE html>
    <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--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>Buffer</title>
    
    <link rel="stylesheet" href="http://js.arcgis.com/3.13/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
    <style>
       html, body {
        height: 100%;
        width: 100%;
        margin: 0; 
        padding: 0;
        overflow:hidden;
      }
      #leftPane{
        color:#000;
        width:250px;
        padding-bottom:15px;
      }
      #map{
        padding:0;
      }
      .details{
        font-size:14px;
        font-weight:600;
        padding-bottom:20px;
      }
    
      button{
        margin:2px;
        cursor:pointer;
      }
    </style>
    
    <script src="http://js.arcgis.com/3.13/"></script>
    <script>
    var map, tb,
            webmapId = "62847ab75c1b4f7d829a530b7c4432f2";
    
    require(["dojo/dom",
    
            "dojo/_base/array",
            "dojo/parser",
            "dojo/query",
            "dojo/on",
    
            "esri/Color",
            "esri/config",
            "esri/map",
            "esri/arcgis/utils",
            "esri/graphic",
    
            "esri/geometry/normalizeUtils",
            "esri/tasks/GeometryService",
            "esri/tasks/BufferParameters",
      
            "esri/toolbars/draw",
      
            "esri/symbols/SimpleMarkerSymbol",
            "esri/symbols/SimpleLineSymbol",
            "esri/symbols/SimpleFillSymbol",
            
            "dijit/layout/BorderContainer",
            "dijit/layout/ContentPane",
            "dijit/form/Button", "dojo/domReady!"
            ],
          function(dom, array, parser, query, on, Color, esriConfig, Map, arcgisUtils, Graphic, normalizeUtils, GeometryService, BufferParameters, Draw, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol){
    
            parser.parse();
    
    
            esriConfig.defaults.geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
    
            esriConfig.defaults.io.proxyUrl = "/proxy/";
            esriConfig.defaults.io.alwaysUseProxy = false;
      
            arcgisUtils.createMap(webmapId, "map").then(function (response) {
            map = response.map;
             initToolbar(map);
            });
           
           //Setup button click handlers
            on(dom.byId("clearGraphics"), "click", function(){
              if(map){
                map.graphics.clear();
              }
            });
            //click handler for the draw tool buttons
            query(".tool").on("click", function(evt){
              if(tb){
               tb.activate(evt.target.id);
              }
            });
            
    
          function initToolbar(mapObj) {
            tb = new Draw(mapObj);
            tb.on("draw-end", doBuffer);
          }
    
          function doBuffer(evtObj) {
            tb.deactivate();
            var geometry = evtObj.geometry, symbol;
            switch (geometry.type) {
               case "point":
                 symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255,0,0]), 1), new Color([0,255,0,0.25]));
                 break;
               case "polyline":
                 symbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255,0,0]), 1);
                 break;
               case "polygon":
                 symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NONE, new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT, new Color([255,0,0]), 2), new Color([255,255,0,0.25]));
                 break;
            }
    
              var graphic = new Graphic(geometry, symbol);
              map.graphics.add(graphic);
    
              //setup the buffer parameters
              var params = new BufferParameters();
              params.distances = [ dom.byId("distance").value ];
              params.outSpatialReference = map.spatialReference;
              params.unit = GeometryService[dom.byId("unit").value];
              //normalize the geometry 
    
              normalizeUtils.normalizeCentralMeridian([geometry]).then(function(normalizedGeometries){
                var normalizedGeometry = normalizedGeometries[0];
                if (normalizedGeometry.type === "polygon") {
                  //if geometry is a polygon then simplify polygon.  This will make the user drawn polygon topologically correct.
                  esriConfig.defaults.geometryService.simplify([normalizedGeometry], function(geometries) {
                    params.geometries = geometries;
                    esriConfig.defaults.geometryService.buffer(params, showBuffer);
                  });
                } else {
                  params.geometries = [normalizedGeometry];
                  esriConfig.defaults.geometryService.buffer(params, showBuffer);
                }
    
              });
            }
    
            function showBuffer(bufferedGeometries) {
              var symbol = new SimpleFillSymbol(
                SimpleFillSymbol.STYLE_SOLID,
                new SimpleLineSymbol(
                  SimpleLineSymbol.STYLE_SOLID,
                  new Color([255,0,0,0.65]), 2
                ),
                new Color([255,0,0,0.35])
              );
    
              array.forEach(bufferedGeometries, function(geometry) {
                var graphic = new Graphic(geometry, symbol);
                map.graphics.add(graphic);
              });
    
            }
      });
    </script>
    
    </head>
    
    <body class="claro">
    <div data-dojo-type="dijit/layout/BorderContainer" 
         data-dojo-props="gutters:'true', design:'sidebar'" 
         style="width:100%;height:100%;">
    
      <div id="map" 
           data-dojo-type="dijit/layout/ContentPane" 
           data-dojo-props="region:'center'">
      </div>
    
      <div id="leftPane" 
           data-dojo-type="dijit/layout/ContentPane" 
           data-dojo-props="region:'left'">
        <div class="details">Pick a tool and draw on the map. The drawn graphic will be buffered based on the specified parameters.</div>
        <button type="button" class="tool" id="line">Line</button>
        <button type="button" class="tool" id="polyline">Polyline</button>
        <button type="button" class="tool" id="freehandpolyline">Freehand Polyline</button>
        <br/>
        <button type="button" class="tool" id="polygon">Polygon</button>
        <button type="button" class="tool" id="freehandpolygon">Freehand Polygon</button>
        <br/><hr />
        <div><b>Buffer Parameters</b></div>
        Distance:&nbsp;<input type="text" id="distance" size="5" value="25" />
        <select id="unit" style="width:100px;">
          <option value="UNIT_STATUTE_MILE">Miles</option>
          <option value="UNIT_FOOT">Feet</option>
          <option value="UNIT_KILOMETER">Kilometers</option>
          <option value="UNIT_METER">Meters</option>
          <option value="UNIT_NAUTICAL_MILE">Nautical Miles</option>
          <option value="UNIT_US_NAUTICAL_MILE">US Nautical Miles</option>
          <option value="UNIT_DEGREE">Degrees</option>
        </select><br />
        <button type="button" id="clearGraphics"  type="button">Clear Graphics</button>
      </div>
    </div>
    </body>
    </html>