Select to view content in your preferred language

Buffer Graphic

2214
13
Jump to solution
09-12-2022 11:36 AM
jaykapalczynski
Frequent Contributor

I have some code below that i am using to allow the user to create a point line or polygon

Each click of the toolbox to chose between each geometry type clears the graphic layer.

What I want to do is:

After the geometry is drawn

  1. Buffer the graphic and write that geometry to another graphic and display it in the map.
  2. I will then need to query for the new graphics geometry and pass this to another function for processing
  • I have a DIV that has the current text for the graphic but I figured it might be better to query the graphic and determine the geometry type?
  • Do I need to select the single graphic in the graphic layer?

Thoughts on the easiest way to do this?

 

Snip from a JSFiddle I was testing in:

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Draw polyline | Sample | ArcGIS API for JavaScript 4.24</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.24/"></script>

    <style>
      html,
      body,
      #viewDiv {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }
      .topcorner{
        position:absolute;
        top:0;
        right:0;
        width: 185px;
        border: 1px solid black;
        text-align: center;
      }
      .topcorner2{
        position:absolute;
        bottom:0;
        right:0;
        width: 185px;
        border: 1px solid black;
        text-align: center;
      }
      </style>
    <script>
  require([
    "esri/Map","esri/views/MapView","esri/views/draw/Draw","esri/Graphic","esri/geometry/geometryEngine","esri/geometry/support/webMercatorUtils",
      "dojo/dom",
      "dojo/domReady!"
  ], (Map, MapView, Draw, Graphic, geometryEngine, webMercatorUtils, dom) => {
  
    var geometryType = "nothing"
  
  
    const map = new Map({
      basemap: "gray-vector"
    });

    const view = new MapView({
      container: "viewDiv",map: map,
      zoom: 10,
      center: [-77.367, 37.55]
    });

    // add the button for the draw tool
    view.ui.add("clear-button", "top-left");
    view.ui.add("line-button", "top-left");
    view.ui.add("point-button", "top-left");
    view.ui.add("polygon-button", "top-left");
    
    const draw = new Draw({
      view: view
    });

    document.getElementById("clear-button").onclick = () => {
      view.graphics.removeAll();    
      geometryType = "nothing";
      document.getElementById("info2").textContent=geometryType;
   };
    document.getElementById("point-button").onclick = () => {
      view.graphics.removeAll();

      geometryType = "point";
      document.getElementById("info2").textContent=geometryType;
      
      // creates and returns an instance of PolyLineDrawAction
      const action = draw.create("point");

      // focus the view to activate keyboard shortcuts for sketching
      view.focus();

     // PointDrawAction.cursor-update
      // Give a visual feedback to users as they move the pointer over the view
      action.on("cursor-update", function (evt) {
        updateVerticesPoint(evt.coordinates);
      });

      // PointDrawAction.draw-complete
      // Create a point when user clicks on the view or presses "C" key.
      action.on("draw-complete", function (evt) {
        updateVerticesPoint(evt.coordinates);
      });
     
    };
    document.getElementById("polygon-button").onclick = () => {
      view.graphics.removeAll();
      
      geometryType = "polygon";
      document.getElementById("info2").textContent=geometryType;
      
      // creates and returns an instance of PolyLineDrawAction
      const action = draw.create("polygon");

      // focus the view to activate keyboard shortcuts for sketching
      view.focus();

      // listen polylineDrawAction events to give immediate visual feedback
      // to users as the line is being drawn on the view.
      action.on(
        [
          "vertex-add",
          "vertex-remove",
          "cursor-update",
          "redo",
          "undo",
          "draw-complete"
        ],
        updateVerticesPolygon
      );
    };
    document.getElementById("line-button").onclick = () => {
      view.graphics.removeAll();

      geometryType = "line";
      document.getElementById("info2").textContent=geometryType;
      
      // creates and returns an instance of PolyLineDrawAction
      const action = draw.create("polyline");

      // focus the view to activate keyboard shortcuts for sketching
      view.focus();

      // listen polylineDrawAction events to give immediate visual feedback
      // to users as the line is being drawn on the view.
      action.on(
        [
          "vertex-add",
          "vertex-remove",
          "cursor-update",
          "redo",
          "undo",
          "draw-complete"
        ],
        updateVerticesLine
      );
    };

    // https://developers.arcgis.com/javascript/latest/esri-icon-font/
    
    function updateVerticesPoint(coordinates) {
      //// create a polyline from returned vertices
      //if (event.vertices.length > 0) {
      //  const result = createGraphicPoint(event);
      //}
      view.graphics.removeAll();
     let point = {
       type: "point", // autocasts as /Point
       x: coordinates[0],
       y: coordinates[1],
       spatialReference: view.spatialReference
     };

     let graphic = new Graphic({
         geometry: point,
         symbol: {
         type: "simple-marker", // autocasts as SimpleMarkerSymbol
         style: "circle",
         color: [51, 102, 153, 0.8],
         size: "16px",
         outline: { // autocasts as SimpleLineSymbol
           color: [0, 0, 0],
           width: 1
         }
       }
     });
     view.graphics.add(graphic);     
    }  
    function updateVerticesPolygon(event) {
      // create a polyline from returned vertices
      if (event.vertices.length > 1) {
        const result = createGraphicPolygon(event);
      }
    }
    function updateVerticesLine(event) {
      // create a polyline from returned vertices
      if (event.vertices.length > 1) {
        const result = createGraphicLine(event);

        // if the last vertex is making the line intersects itself,
        // prevent the events from firing
        if (result.selfIntersects) {
          event.preventDefault();
        }
      }
    }

    
    function createGraphicPoint(event) {      
      const vertices = event.vertices;
      view.graphics.removeAll();

      //          
      // a graphic representing the polyline that is being drawn
      const graphicPoly = new Graphic({
        geometry: {
          type: "point",
          spatialReference: view.spatialReference
        },
        symbol: {
          type: "simple-marker", // autocasts as new SimpleFillSymbol
          color: [51, 102, 153, 0.8],
          outline: {
             color: [255, 255, 255],
             width: 1
          }
        }

      });
     
      view.graphics.add(graphicPoly);
    }
    function createGraphicPolygon(event) {
      const vertices = event.vertices;
      view.graphics.removeAll();

      // a graphic representing the polyline that is being drawn
      const graphicPoly = new Graphic({
        geometry: {
          type: "polygon",
          rings: vertices,
          spatialReference: view.spatialReference
        },
        symbol: {
          type: "simple-fill", // autocasts as new SimpleFillSymbol
          color: [227, 139, 79, 0.8],
          outline: {
             color: [45, 55, 255],
             width: 1
          }
        }

      });
     
      view.graphics.add(graphicPoly);
    }
    function createGraphicLine(event) {
      const vertices = event.vertices;
      view.graphics.removeAll();

      // a graphic representing the polyline that is being drawn
      const graphicLine = new Graphic({
        geometry: {
          type: "polyline",
          paths: vertices,
          spatialReference: view.spatialReference
        },
        symbol: {
          type: "simple-line", // autocasts as new SimpleFillSymbol
          color: [4, 90, 141],
          width: 1,
          cap: "round",
          join: "round"
        }
      });

      // check if the polyline intersects itself.
      const intersectingSegment = getIntersectingSegment(graphicLine.geometry);

      // Add a new graphic for the intersecting segment.
      if (intersectingSegment) {
        view.graphics.addMany([graphicLine, intersectingSegment]);
      }
      // Just add the graphic representing the polyline if no intersection
      else {
        view.graphics.add(graphicLine);
      }

      // return intersectingSegment
      return {
        selfIntersects: intersectingSegment
      };
    }

    // function that checks if the line intersects itself
    function isSelfIntersecting(polyline) {
      if (polyline.paths[0].length < 3) {
        return false;
      }
      const line = polyline.clone();

      //get the last segment from the polyline that is being drawn
      const lastSegment = getLastSegment(polyline);
      line.removePoint(0, line.paths[0].length - 1);

      // returns true if the line intersects itself, false otherwise
      return geometryEngine.crosses(lastSegment, line);
    }
    // Checks if the line intersects itself. If yes, change the last
    // segment's symbol giving a visual feedback to the user.
    function getIntersectingSegment(polyline) {
      if (isSelfIntersecting(polyline)) {
        return new Graphic({
          geometry: getLastSegment(polyline),
          symbol: {
            type: "simple-line", // autocasts as new SimpleLineSymbol
            style: "short-dot",
            width: 3.5,
            color: "yellow"
          }
        });
      }
      return null;
    }
    // Get the last segment of the polyline that is being drawn
    function getLastSegment(polyline) {
      const line = polyline.clone();
      const lastXYPoint = line.removePoint(0, line.paths[0].length - 1);
      const existingLineFinalPoint = line.getPoint(
        0,
        line.paths[0].length - 1
      );

      return {
        type: "polyline",
        spatialReference: view.spatialReference,
        hasZ: false,
        paths: [
          [
            [existingLineFinalPoint.x, existingLineFinalPoint.y],
            [lastXYPoint.x, lastXYPoint.y]
          ]
        ]
      };
    }
 
       function showCoordinates(evt) {
        var point = view.toMap({x: evt.x, y: evt.y});
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(6) + ", " + mp.y.toFixed(6);
      }

      view.when(function(){
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });
 
 });
</script>
  </head>

  <body>
    <!-- https://developers.arcgis.com/javascript/latest/esri-icon-font/ -->
    <div id="viewDiv">
      <div id="clear-button" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
        <span class="esri-icon-erase"></span>           
      </div> 
      <div id="point-button" class="esri-widget esri-widget--button esri-interactive" title="Draw point">
        <span class="esri-icon-map-pin"></span>           
      </div> 
      <div id="line-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polyline">
        <span class="esri-icon-polyline"></span>           
      </div>
      <div id="polygon-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
        <span class="esri-icon-polygon"></span>   
      </div>   
  
      <div class="topcorner">
         <span id="info" ></span>     
      </div>      
      <div class="topcorner2">
         <div id="info2">fghfghf</div>     
      </div>               
    </div>
  </body>
</html>

 

 

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Jay, So here is what I would do.

<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Draw polyline | Sample | ArcGIS API for JavaScript 4.24</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.24/"></script>

  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    .topcorner {
      position: absolute;
      top: 0;
      right: 0;
      width: 185px;
      border: 1px solid black;
      text-align: center;
    }

    .topcorner2 {
      position: absolute;
      bottom: 16;
      right: 0;
      width: 185px;
      border: 1px solid black;
      text-align: center;
    }
  </style>
  <script>
    require([
      "esri/Map", "esri/views/MapView", "esri/views/draw/Draw", "esri/Graphic", "esri/geometry/geometryEngine",
      "esri/geometry/support/webMercatorUtils",
      "esri/layers/GraphicsLayer",
      "dojo/dom",
      "dojo/domReady!"
    ], (Map, MapView, Draw, Graphic, geometryEngine, webMercatorUtils, GraphicsLayer, dom) => {

      var geometryType = "nothing"
      let bufferGralayer = new GraphicsLayer({id: "BufferGraLyr"});

      const map = new Map({
        basemap: "gray-vector",
        layers: [bufferGralayer]
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 10,
        center: [-77.367, 37.55]
      });

      // add the button for the draw tool
      view.ui.add("clear-button", "top-left");
      view.ui.add("line-button", "top-left");
      view.ui.add("point-button", "top-left");
      view.ui.add("polygon-button", "top-left");

      const draw = new Draw({
        view: view
      });

      document.getElementById("clear-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryType = "nothing";
        document.getElementById("info2").textContent = geometryType;
      };
      document.getElementById("point-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "point";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("point");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // PointDrawAction.cursor-update
        // Give a visual feedback to users as they move the pointer over the view
        action.on("cursor-update", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

        // PointDrawAction.draw-complete
        // Create a point when user clicks on the view or presses "C" key.
        action.on("draw-complete", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

      };
      document.getElementById("polygon-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "polygon";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polygon");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesPolygon
        );
      };
      document.getElementById("line-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "line";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polyline");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesLine
        );
      };

      // https://developers.arcgis.com/javascript/latest/esri-icon-font/

      function updateVerticesPoint(coordinates) {
        //// create a polyline from returned vertices
        //if (event.vertices.length > 0) {
        //  const result = createGraphicPoint(event);
        //}
        view.graphics.removeAll();
        let point = {
          type: "point", // autocasts as /Point
          x: coordinates[0],
          y: coordinates[1],
          spatialReference: view.spatialReference
        };

        let graphic = new Graphic({
          geometry: point,
          symbol: {
            type: "simple-marker", // autocasts as SimpleMarkerSymbol
            style: "circle",
            color: [51, 102, 153, 0.8],
            size: "16px",
            outline: { // autocasts as SimpleLineSymbol
              color: [0, 0, 0],
              width: 1
            }
          }
        });
        view.graphics.add(graphic);
        BufferGeom(graphic.geometry, 500);
      }

      function updateVerticesPolygon(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicPolygon(event);
        }
      }

      function updateVerticesLine(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicLine(event);

          // if the last vertex is making the line intersects itself,
          // prevent the events from firing
          if (result.selfIntersects) {
            event.preventDefault();
          }
        }
      }


      function createGraphicPoint(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        //          
        // a graphic representing the polyline that is being drawn
        const graphicPnt= new Graphic({
          geometry: {
            type: "point",
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-marker", // autocasts as new SimpleFillSymbol
            color: [51, 102, 153, 0.8],
            outline: {
              color: [255, 255, 255],
              width: 1
            }
          }

        });

        view.graphics.add(graphicPnt);
        BufferGeom(graphicPnt.geometry, 500);
      }

      function createGraphicPolygon(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicPoly = new Graphic({
          geometry: {
            type: "polygon",
            rings: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-fill", // autocasts as new SimpleFillSymbol
            color: [227, 139, 79, 0.8],
            outline: {
              color: [45, 55, 255],
              width: 1
            }
          }

        });

        view.graphics.add(graphicPoly);
        BufferGeom(graphicPoly.geometry, 500);
      }

      function createGraphicLine(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicLine = new Graphic({
          geometry: {
            type: "polyline",
            paths: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-line", // autocasts as new SimpleFillSymbol
            color: [4, 90, 141],
            width: 1,
            cap: "round",
            join: "round"
          }
        });

        // check if the polyline intersects itself.
        const intersectingSegment = getIntersectingSegment(graphicLine.geometry);

        // Add a new graphic for the intersecting segment.
        if (intersectingSegment) {
          view.graphics.addMany([graphicLine, intersectingSegment]);
        }
        // Just add the graphic representing the polyline if no intersection
        else {
          view.graphics.add(graphicLine);
          BufferGeom(graphicLine.geometry, 500);
        }

        // return intersectingSegment
        return {
          selfIntersects: intersectingSegment
        };
      }

      function BufferGeom(geom, dist) {
        const buffGeom = geometryEngine.buffer(geom, dist, "feet");
        const buffgra = new Graphic({
          geometry: buffGeom,
          symbol: getGeomSymbol()
        });
        bufferGralayer.removeAll();
        bufferGralayer.add(buffgra)
      }

      function getGeomSymbol() {
        let sym;
        switch(geometryType) {
          case "point":
            sym = {
              style: "circle",
              size: 22,
              type: "simple-marker",
              color: [255, 0, 0, 0.8],
              outline: {
                color: [255, 0, 0],
                width: 1
              }
            }
            break;
          case "line":
          case "polygon":
            sym = {
              type: "simple-fill", // autocasts as new SimpleFillSymbol
              color: [255, 0, 0],
              width: 1,
              cap: "round",
              join: "round"
            }
            break;
          default :
            sym = null;
        }
        return sym;
      }

      // function that checks if the line intersects itself
      function isSelfIntersecting(polyline) {
        if (polyline.paths[0].length < 3) {
          return false;
        }
        const line = polyline.clone();

        //get the last segment from the polyline that is being drawn
        const lastSegment = getLastSegment(polyline);
        line.removePoint(0, line.paths[0].length - 1);

        // returns true if the line intersects itself, false otherwise
        return geometryEngine.crosses(lastSegment, line);
      }

      // Checks if the line intersects itself. If yes, change the last
      // segment's symbol giving a visual feedback to the user.
      function getIntersectingSegment(polyline) {
        if (isSelfIntersecting(polyline)) {
          return new Graphic({
            geometry: getLastSegment(polyline),
            symbol: {
              type: "simple-line", // autocasts as new SimpleLineSymbol
              style: "short-dot",
              width: 3.5,
              color: "yellow"
            }
          });
        }
        return null;
      }
      // Get the last segment of the polyline that is being drawn
      function getLastSegment(polyline) {
        const line = polyline.clone();
        const lastXYPoint = line.removePoint(0, line.paths[0].length - 1);
        const existingLineFinalPoint = line.getPoint(
          0,
          line.paths[0].length - 1
        );

        return {
          type: "polyline",
          spatialReference: view.spatialReference,
          hasZ: false,
          paths: [
            [
              [existingLineFinalPoint.x, existingLineFinalPoint.y],
              [lastXYPoint.x, lastXYPoint.y]
            ]
          ]
        };
      }

      function showCoordinates(evt) {
        var point = view.toMap({
          x: evt.x,
          y: evt.y
        });
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(6) + ", " + mp.y.toFixed(6);
      }

      view.when(function () {
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });

    });
  </script>
</head>

<body>
  <!-- https://developers.arcgis.com/javascript/latest/esri-icon-font/ -->
  <div id="viewDiv">
    <div id="clear-button" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
      <span class="esri-icon-erase"></span>
    </div>
    <div id="point-button" class="esri-widget esri-widget--button esri-interactive" title="Draw point">
      <span class="esri-icon-map-pin"></span>
    </div>
    <div id="line-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polyline">
      <span class="esri-icon-polyline"></span>
    </div>
    <div id="polygon-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
      <span class="esri-icon-polygon"></span>
    </div>

    <div class="topcorner">
      <span id="info"></span>
    </div>
    <div class="topcorner2">
      <div id="info2">fghfghf</div>
    </div>
  </div>
</body>

</html>

View solution in original post

13 Replies
jaykapalczynski
Frequent Contributor

I have seen this example but this is JS 3.x

https://developers.arcgis.com/javascript/3/sandbox/sandbox.html?sample=util_buffergraphic

 

I am in 4.x... I think I should be able to do something similar right after I draw one of the graphics?

Im not finding a buffer like the one in 3.x  Maybe I should be doing this a different way?

0 Kudos
jaykapalczynski
Frequent Contributor

OK so I tried to simply this script to just polygons.  I am confused on how to get the geometry of the graphic the user draws to a buffer function, then to write that buffer to a new graphic. 

Any thoughts?  Am I off the mark here.

 

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Draw polyline | Sample | ArcGIS API for JavaScript 4.24</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.24/"></script>

    <style>
      html,
      body,
      #viewDiv {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }
      </style>
    <script>
  require([
    "esri/Map","esri/views/MapView","esri/views/draw/Draw","esri/Graphic","esri/geometry/geometryEngine","esri/geometry/support/webMercatorUtils",
    "esri/rest/geometryService", 
    "dojo/dom",
    "dojo/domReady!"
  ], (Map, MapView, Draw, Graphic, geometryEngine, webMercatorUtils, geometryService, dom) => {
 
    //esriConfig.defaults.geometryService = new GeometryService("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer");

    const map = new Map({
      basemap: "gray-vector"
    });

    const view = new MapView({
      container: "viewDiv",
      map: map,
      zoom: 10,
      center: [-77.367, 37.55]
    });

    // add the button for the draw tool
    view.ui.add("clear-button", "top-left");
    view.ui.add("polygon-button", "top-left");
    
    const draw = new Draw({
      view: view
    });

    document.getElementById("clear-button").onclick = () => {
      view.graphics.removeAll();    
   };

    document.getElementById("polygon-button").onclick = () => {
      view.graphics.removeAll();
      
      // creates and returns an instance of PolyLineDrawAction
      const action = draw.create("polygon");

      // focus the view to activate keyboard shortcuts for sketching
      view.focus();

      // listen polylineDrawAction events to give immediate visual feedback
      // to users as the line is being drawn on the view.
      action.on(
        [
          "vertex-add",
          "vertex-remove",
          "cursor-update",
          "redo",
          "undo",
          "draw-complete"
        ],
        updateVerticesPolygon
      );
    };

    function updateVerticesPolygon(event) {
      // create a polyline from returned vertices
      if (event.vertices.length > 1) {
        const result = createGraphicPolygon(event);
      }
    }

    function createGraphicPolygon(event) {
      const vertices = event.vertices;
      view.graphics.removeAll();
      
        // a graphic representing the polyline that is being drawn
      const graphicPoly = new Graphic({
        geometry: {
          type: "polygon",
          rings: vertices,
          spatialReference: view.spatialReference
        },
        symbol: {
          type: "simple-fill", // autocasts as new SimpleFillSymbol
          color: [227, 139, 79, 0.8],
          outline: {
             color: [45, 55, 255],
             width: 1
          }
        }
      });
      
      view.graphics.add(graphicPoly)
      // PASS GEOMETRY TO BUFFER FUNCTION AND ADD TO NEW GRAPHIC???
    }

    function createBuffer(event) {      
     const graphicsFinal = new Graphic({
        geometry: {
          type: "polygon",
          rings: vertices,
          spatialReference: view.spatialReference
        },
        symbol: {
          type: "simple-fill", // autocasts as new SimpleFillSymbol
          color: [227, 139, 79, 0.8],
          outline: {
             color: [45, 55, 255],
             width: 1
          }
        }
      });
 
   //bufferSpatialReference: new SpatialReference({wkid: 3857}),
   //   geometries: graphicPoly
      const params = new BufferParameters({
        distances: [560],
        unit: "kilometers",
        geodesic: true,
        outSpatialReference: view.spatialReference //,
      });

        var url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer"

      buffer(url, params).then(function(results){
            graphicsFinal.add(new Graphic({
           geometry: results[0]
        }));
      });  
   }
 });
</script>
  </head>

  <body>
    <!-- https://developers.arcgis.com/javascript/latest/esri-icon-font/ -->
    <div id="viewDiv">
      <div id="clear-button" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
        <span class="esri-icon-erase"></span>           
      </div> 
      <div id="polygon-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
        <span class="esri-icon-polygon"></span>   
      </div>   
    </div>
  </body>
</html>

 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jay, So here is what I would do.

<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Draw polyline | Sample | ArcGIS API for JavaScript 4.24</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.24/"></script>

  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    .topcorner {
      position: absolute;
      top: 0;
      right: 0;
      width: 185px;
      border: 1px solid black;
      text-align: center;
    }

    .topcorner2 {
      position: absolute;
      bottom: 16;
      right: 0;
      width: 185px;
      border: 1px solid black;
      text-align: center;
    }
  </style>
  <script>
    require([
      "esri/Map", "esri/views/MapView", "esri/views/draw/Draw", "esri/Graphic", "esri/geometry/geometryEngine",
      "esri/geometry/support/webMercatorUtils",
      "esri/layers/GraphicsLayer",
      "dojo/dom",
      "dojo/domReady!"
    ], (Map, MapView, Draw, Graphic, geometryEngine, webMercatorUtils, GraphicsLayer, dom) => {

      var geometryType = "nothing"
      let bufferGralayer = new GraphicsLayer({id: "BufferGraLyr"});

      const map = new Map({
        basemap: "gray-vector",
        layers: [bufferGralayer]
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 10,
        center: [-77.367, 37.55]
      });

      // add the button for the draw tool
      view.ui.add("clear-button", "top-left");
      view.ui.add("line-button", "top-left");
      view.ui.add("point-button", "top-left");
      view.ui.add("polygon-button", "top-left");

      const draw = new Draw({
        view: view
      });

      document.getElementById("clear-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryType = "nothing";
        document.getElementById("info2").textContent = geometryType;
      };
      document.getElementById("point-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "point";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("point");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // PointDrawAction.cursor-update
        // Give a visual feedback to users as they move the pointer over the view
        action.on("cursor-update", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

        // PointDrawAction.draw-complete
        // Create a point when user clicks on the view or presses "C" key.
        action.on("draw-complete", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

      };
      document.getElementById("polygon-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "polygon";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polygon");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesPolygon
        );
      };
      document.getElementById("line-button").onclick = () => {
        view.graphics.removeAll();

        geometryType = "line";
        document.getElementById("info2").textContent = geometryType;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polyline");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesLine
        );
      };

      // https://developers.arcgis.com/javascript/latest/esri-icon-font/

      function updateVerticesPoint(coordinates) {
        //// create a polyline from returned vertices
        //if (event.vertices.length > 0) {
        //  const result = createGraphicPoint(event);
        //}
        view.graphics.removeAll();
        let point = {
          type: "point", // autocasts as /Point
          x: coordinates[0],
          y: coordinates[1],
          spatialReference: view.spatialReference
        };

        let graphic = new Graphic({
          geometry: point,
          symbol: {
            type: "simple-marker", // autocasts as SimpleMarkerSymbol
            style: "circle",
            color: [51, 102, 153, 0.8],
            size: "16px",
            outline: { // autocasts as SimpleLineSymbol
              color: [0, 0, 0],
              width: 1
            }
          }
        });
        view.graphics.add(graphic);
        BufferGeom(graphic.geometry, 500);
      }

      function updateVerticesPolygon(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicPolygon(event);
        }
      }

      function updateVerticesLine(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicLine(event);

          // if the last vertex is making the line intersects itself,
          // prevent the events from firing
          if (result.selfIntersects) {
            event.preventDefault();
          }
        }
      }


      function createGraphicPoint(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        //          
        // a graphic representing the polyline that is being drawn
        const graphicPnt= new Graphic({
          geometry: {
            type: "point",
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-marker", // autocasts as new SimpleFillSymbol
            color: [51, 102, 153, 0.8],
            outline: {
              color: [255, 255, 255],
              width: 1
            }
          }

        });

        view.graphics.add(graphicPnt);
        BufferGeom(graphicPnt.geometry, 500);
      }

      function createGraphicPolygon(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicPoly = new Graphic({
          geometry: {
            type: "polygon",
            rings: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-fill", // autocasts as new SimpleFillSymbol
            color: [227, 139, 79, 0.8],
            outline: {
              color: [45, 55, 255],
              width: 1
            }
          }

        });

        view.graphics.add(graphicPoly);
        BufferGeom(graphicPoly.geometry, 500);
      }

      function createGraphicLine(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicLine = new Graphic({
          geometry: {
            type: "polyline",
            paths: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-line", // autocasts as new SimpleFillSymbol
            color: [4, 90, 141],
            width: 1,
            cap: "round",
            join: "round"
          }
        });

        // check if the polyline intersects itself.
        const intersectingSegment = getIntersectingSegment(graphicLine.geometry);

        // Add a new graphic for the intersecting segment.
        if (intersectingSegment) {
          view.graphics.addMany([graphicLine, intersectingSegment]);
        }
        // Just add the graphic representing the polyline if no intersection
        else {
          view.graphics.add(graphicLine);
          BufferGeom(graphicLine.geometry, 500);
        }

        // return intersectingSegment
        return {
          selfIntersects: intersectingSegment
        };
      }

      function BufferGeom(geom, dist) {
        const buffGeom = geometryEngine.buffer(geom, dist, "feet");
        const buffgra = new Graphic({
          geometry: buffGeom,
          symbol: getGeomSymbol()
        });
        bufferGralayer.removeAll();
        bufferGralayer.add(buffgra)
      }

      function getGeomSymbol() {
        let sym;
        switch(geometryType) {
          case "point":
            sym = {
              style: "circle",
              size: 22,
              type: "simple-marker",
              color: [255, 0, 0, 0.8],
              outline: {
                color: [255, 0, 0],
                width: 1
              }
            }
            break;
          case "line":
          case "polygon":
            sym = {
              type: "simple-fill", // autocasts as new SimpleFillSymbol
              color: [255, 0, 0],
              width: 1,
              cap: "round",
              join: "round"
            }
            break;
          default :
            sym = null;
        }
        return sym;
      }

      // function that checks if the line intersects itself
      function isSelfIntersecting(polyline) {
        if (polyline.paths[0].length < 3) {
          return false;
        }
        const line = polyline.clone();

        //get the last segment from the polyline that is being drawn
        const lastSegment = getLastSegment(polyline);
        line.removePoint(0, line.paths[0].length - 1);

        // returns true if the line intersects itself, false otherwise
        return geometryEngine.crosses(lastSegment, line);
      }

      // Checks if the line intersects itself. If yes, change the last
      // segment's symbol giving a visual feedback to the user.
      function getIntersectingSegment(polyline) {
        if (isSelfIntersecting(polyline)) {
          return new Graphic({
            geometry: getLastSegment(polyline),
            symbol: {
              type: "simple-line", // autocasts as new SimpleLineSymbol
              style: "short-dot",
              width: 3.5,
              color: "yellow"
            }
          });
        }
        return null;
      }
      // Get the last segment of the polyline that is being drawn
      function getLastSegment(polyline) {
        const line = polyline.clone();
        const lastXYPoint = line.removePoint(0, line.paths[0].length - 1);
        const existingLineFinalPoint = line.getPoint(
          0,
          line.paths[0].length - 1
        );

        return {
          type: "polyline",
          spatialReference: view.spatialReference,
          hasZ: false,
          paths: [
            [
              [existingLineFinalPoint.x, existingLineFinalPoint.y],
              [lastXYPoint.x, lastXYPoint.y]
            ]
          ]
        };
      }

      function showCoordinates(evt) {
        var point = view.toMap({
          x: evt.x,
          y: evt.y
        });
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(6) + ", " + mp.y.toFixed(6);
      }

      view.when(function () {
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });

    });
  </script>
</head>

<body>
  <!-- https://developers.arcgis.com/javascript/latest/esri-icon-font/ -->
  <div id="viewDiv">
    <div id="clear-button" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
      <span class="esri-icon-erase"></span>
    </div>
    <div id="point-button" class="esri-widget esri-widget--button esri-interactive" title="Draw point">
      <span class="esri-icon-map-pin"></span>
    </div>
    <div id="line-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polyline">
      <span class="esri-icon-polyline"></span>
    </div>
    <div id="polygon-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
      <span class="esri-icon-polygon"></span>
    </div>

    <div class="topcorner">
      <span id="info"></span>
    </div>
    <div class="topcorner2">
      <div id="info2">fghfghf</div>
    </div>
  </div>
</body>

</html>
jaykapalczynski
Frequent Contributor

Ok thanks... 

One more question... How then do I query for the geometry of the buffered section... I need to get this geometry to pass onto a GP tool to do further processing...

I assume that I can query for the graphics in the new Graphics Layer that was created "bufferGraLayer"?

 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jay,  You are on the right tract with the distance and unit stuff. A far as querying the buffer graphic. Just get the graphic from the bufferGraLayer graphics property.

let buffGeom = bufferGraLayer.graphics[0].geometry;

Or just keep a global var of the buffGeom in your app from the BufferGeom function.

0 Kudos
jaykapalczynski
Frequent Contributor

deleted

0 Kudos
jaykapalczynski
Frequent Contributor

I got it....wrote it to a global variable like you mentioned...firing the result off by Button click to verify it was working....

THANKS @RobertScheitlin__GISP 

 

      var testGeometry = "";

      document.getElementById("getGeometry-button").onclick = () => {
          alert(JSON.stringify(testGeometry));
      };

      function BufferGeom(geom, dist) {
        var d = document.getElementById("distance").value;
        var t = document.getElementById("distanceType").value;        
       
        const buffGeom = geometryEngine.buffer(geom, d, t);
        testGeometry = buffGeom;

        const buffgra = new Graphic({
          geometry: buffGeom,
          symbol: getGeomSymbol()
        });
        bufferGralayer.removeAll();
        bufferGralayer.add(buffgra)

      }

 

0 Kudos
jaykapalczynski
Frequent Contributor

If anyone is interested here is the full code... 

Chose between geometry types, draw shapes, buffer shapes, return geometry

 

 

<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Draw polyline | Sample | ArcGIS API for JavaScript 4.24</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.24/"></script>

  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      margin: 20;
      padding: 20;
    }
    .ext-box { 
      display: table; 
      width:350px;
      height:100%;
    }
    .int-box { 
      display: table-cell; 
      vertical-align: top; 
      width:340px;
      height:260px;
    }
    .FixedHeightContainer{
      float:left;
      height: 380px;
      width:230px; 
      padding:3px;
      background:rgb(112,128,144,0.5);
    }
    .header{
      height: 30px;
      padding-top: 5px;
    }
    .geometryResultsdiv
    {
      height:345px;
      overflow:auto;
      background:#fff;
      font-size: 8px;
    }
    .menu {
        display: table;
        width: 65%;
        border: 1px solid black;
        border-right: none;
        box-sizing: border-box;
    }
    .menu > div {
        display: table-row;
        background-color: white;
    }
    .menu > div >div {
        border-right: 1px solid black;
        display: table-cell;
        text-align: center;
        vertical-align: middle;
    }
    @media screen and (max-width: 240px) {
        .menu {
            display: block;
            float: left;
            width: auto;
            border: none;
        }
        .menu > div {
            display: block;
        }
        .menu > div > div {
            border: none;
            padding-right: 10px;
            display: block;
            text-align: left;
        }
    }
    .boxpadding{
        padding: 0px 0px 5px 8px; 
    }
    .float-container {
        border: 3px solid #fff;
        padding: 2px;
    }
    .float-child1 {
        width: 40%;
        float: left;
        padding: 2px;
    }  
    .float-child2 {
        width: 25%;
        float: left;
        padding: 2px;
    }  
  </style>
  
  <script>

   function valDistance() {
    d = document.getElementById("distance").value;
    document.getElementById("infoDistance").textContent = "Distance: " + d;
		}
   function valType() {
    t = document.getElementById("distanceType").value;
    document.getElementById("infoType").textContent = "Type: " + t;
		}  
  
    require([
      "esri/Map", "esri/views/MapView", "esri/views/draw/Draw", "esri/Graphic", "esri/geometry/geometryEngine",
      "esri/geometry/support/webMercatorUtils",
      "esri/layers/GraphicsLayer",
      "dojo/dom",
      "dojo/domReady!"
    ], (Map, MapView, Draw, Graphic, geometryEngine, webMercatorUtils, GraphicsLayer, dom) => {


      // https://developers.arcgis.com/javascript/latest/esri-icon-font/
      
      var geometryType = ""
      var geometryInfo = "No Geometry Selected"
      let bufferGralayer = new GraphicsLayer({id: "BufferGraLyr",});
			bufferGralayer.opacity = 0.5;			
      
      const map = new Map({
        basemap: "gray-vector",
        layers: [bufferGralayer]
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 10,
        center: [-77.367, 37.55]
      });

      // add the button for the draw tool
      view.ui.add("clear-button", "top-left");
      view.ui.add("line-button", "top-left");
      view.ui.add("point-button", "top-left");
      view.ui.add("polygon-button", "top-left");

      const draw = new Draw({
        view: view
      });

      // THIS IS FOR THE BUTTONS IN THE SIDE BAR
      document.getElementById("clear-button2").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryInfo = "No Geometry Selected";
        document.getElementById("info2").textContent = geometryInfo;
        document.getElementById("geometryResultsdiv").textContent = "";
      };
      document.getElementById("point-button2").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();  
        geometryInfo = "point";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;
        const action = draw.create("point");
        view.focus();
        action.on("cursor-update", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });
        action.on("draw-complete", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });
      };
      document.getElementById("polygon-button2").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();  
        geometryInfo = "polygon";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;
        const action = draw.create("polygon");
        view.focus();
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesPolygon
        );
      };
      document.getElementById("line-button2").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();       
        geometryInfo = "line";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;
        const action = draw.create("polyline");
        view.focus();
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesLine
        );
      };

      // THIS IS FOR THE BUTTONS IN THE VIEW ITSELF
      document.getElementById("clear-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryInfo = "No Geometry Selected";
        document.getElementById("info2").textContent = geometryInfo;
        document.getElementById("geometryResultsdiv").textContent = "";
      };
      document.getElementById("point-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryInfo = "point";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("point");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // PointDrawAction.cursor-update
        // Give a visual feedback to users as they move the pointer over the view
        action.on("cursor-update", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

        // PointDrawAction.draw-complete
        // Create a point when user clicks on the view or presses "C" key.
        action.on("draw-complete", function (evt) {
          updateVerticesPoint(evt.coordinates);
        });

      };
      document.getElementById("polygon-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryInfo = "polygon";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polygon");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesPolygon
        );
      };
      document.getElementById("line-button").onclick = () => {
        view.graphics.removeAll();
        bufferGralayer.removeAll();
        geometryInfo = "line";
        document.getElementById("info2").textContent = "Geometry: " + geometryInfo;

        // creates and returns an instance of PolyLineDrawAction
        const action = draw.create("polyline");

        // focus the view to activate keyboard shortcuts for sketching
        view.focus();

        // listen polylineDrawAction events to give immediate visual feedback
        // to users as the line is being drawn on the view.
        action.on(
          [
            "vertex-add",
            "vertex-remove",
            "cursor-update",
            "redo",
            "undo",
            "draw-complete"
          ],
          updateVerticesLine
        );
      };
      
      // Set variable to hold the Geometry that the Users Created. 
      var userDefinedGeometry = "";
      
      function updateVerticesPoint(coordinates) {
        //// create a polyline from returned vertices
        view.graphics.removeAll();
        let point = {
          type: "point", // autocasts as /Point
          x: coordinates[0],
          y: coordinates[1],
          spatialReference: view.spatialReference
        };

        let graphicPoint = new Graphic({
          geometry: point,
          symbol: {
            type: "simple-marker", // autocasts as SimpleMarkerSymbol
            style: "circle",
            size: "16px",
            color: [70,90,141, 0.4],
            outline: {
              color: [47,76,119,0.5],
              width: 1
            }
          }
        });
        view.graphics.add(graphicPoint);
        BufferGeom(graphicPoint.geometry);
      }          
      function updateVerticesPolygon(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicPolygon(event);
        }
      }
      function updateVerticesLine(event) {
        // create a polyline from returned vertices
        if (event.vertices.length > 1) {
          const result = createGraphicLine(event);

          // if the last vertex is making the line intersects itself,
          // prevent the events from firing
          if (result.selfIntersects) {
            event.preventDefault();
          }
        }
      }

/*
      function createGraphicPoint(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();
       
        // a graphic representing the polyline that is being drawn
        const graphicPnt= new Graphic({
          geometry: {
            type: "point",
            paths: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-marker", // autocasts as new SimpleFillSymbol
            color: [255,255,255,0.9], //[70,90,141,0.2],
            opacity: 0.2,
            outline: {
              color: [255,255,255, 0.9], //[47,76,119, 0.2],
              width: 1
            }
          }

        });

        view.graphics.add(graphicPnt);
        BufferGeom(graphicPnt.geometry);
      }
*/
      function createGraphicPolygon(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicPoly = new Graphic({
          geometry: {
            type: "polygon",
            rings: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-fill", // autocasts as new SimpleFillSymbol
            color: [70,90,141, 0.4],
            outline: {
              color: [47,76,119],
              width: 1
            }
          }
        });
        
        view.graphics.add(graphicPoly);
        BufferGeom(graphicPoly.geometry);
      }
      function createGraphicLine(event) {
        const vertices = event.vertices;
        view.graphics.removeAll();

        // a graphic representing the polyline that is being drawn
        const graphicLine = new Graphic({
          geometry: {
            type: "polyline",
            paths: vertices,
            spatialReference: view.spatialReference
          },
          symbol: {
            type: "simple-line", // autocasts as new SimpleFillSymbol
            color: [70,90,141, 0.4],
            width: 1,
            cap: "round",
            join: "round"
          }
        });

        // check if the polyline intersects itself.
        const intersectingSegment = getIntersectingSegment(graphicLine.geometry);

        // Add a new graphic for the intersecting segment.
        if (intersectingSegment) {
          view.graphics.addMany([graphicLine, intersectingSegment]);
        }
        // Just add the graphic representing the polyline if no intersection
        else {
          view.graphics.add(graphicLine);
          BufferGeom(graphicLine.geometry);
        }
        // return intersectingSegment
        return {
          selfIntersects: intersectingSegment
        };
      }

      function BufferGeom(geom) {
        var d = document.getElementById("distance").value;
        var t = document.getElementById("distanceType").value;        
        
        const buffGeom = geometryEngine.buffer(geom, d, t);
        // Set Global Variable to hold the Geometry
        userDefinedGeometry = buffGeom;
        
        const buffgra = new Graphic({
          geometry: buffGeom,
          symbol: getGeomSymbol()
        });
        bufferGralayer.removeAll();
        bufferGralayer.add(buffgra)
          
        document.getElementById("geometryResultsdiv").innerText = JSON.stringify(userDefinedGeometry);   
      }
      function getGeomSymbol() {
        let sym;
        switch(geometryType) {
          case "point":
            sym = {
              style: "circle",
              size: 22,
              type: "simple-marker",
              color: [112,128,144, 0.9],
              outline: {
                color: [112,128,144, 0.9],
                width: 1
              }
            }
            break;
          case "line":
          case "polygon":
            sym = {
              type: "simple-fill", // autocasts as new SimpleFillSymbol
              color: [112,128,144],
              width: 1,
              cap: "round",
              join: "round"
            }
            break;
          default :
            sym = null;
        }
        return sym;
      }
      
      // function that checks if the line intersects itself
      function isSelfIntersecting(polyline) {
        if (polyline.paths[0].length < 3) {
          return false;
        }
        const line = polyline.clone();

        //get the last segment from the polyline that is being drawn
        const lastSegment = getLastSegment(polyline);
        line.removePoint(0, line.paths[0].length - 1);

        // returns true if the line intersects itself, false otherwise
        return geometryEngine.crosses(lastSegment, line);
      }
      // Checks if the line intersects itself. If yes, change the last
      // segment's symbol giving a visual feedback to the user.
      function getIntersectingSegment(polyline) {
        if (isSelfIntersecting(polyline)) {
          return new Graphic({
            geometry: getLastSegment(polyline),
            symbol: {
              type: "simple-line", // autocasts as new SimpleLineSymbol
              style: "short-dot",
              width: 3.5,
              color: "yellow"
            }
          });
        }
        return null;
      }
      // Get the last segment of the polyline that is being drawn
      function getLastSegment(polyline) {
        const line = polyline.clone();
        const lastXYPoint = line.removePoint(0, line.paths[0].length - 1);
        const existingLineFinalPoint = line.getPoint(
          0,
          line.paths[0].length - 1
        );

        return {
          type: "polyline",
          spatialReference: view.spatialReference,
          hasZ: false,
          paths: [
            [
              [existingLineFinalPoint.x, existingLineFinalPoint.y],
              [lastXYPoint.x, lastXYPoint.y]
            ]
          ]
        };
      }
      function showCoordinates(evt) {
        var point = view.toMap({
          x: evt.x,
          y: evt.y
        });
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(6) + ", " + mp.y.toFixed(6);
      }
      view.when(function () {
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });

    });
  </script>
</head>

<body>
  <div id="viewDiv">
    <div id="clear-button" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
      <span class="esri-icon-erase"></span>
    </div> 
    <div id="point-button" class="esri-widget esri-widget--button esri-interactive" title="Draw point">
      <span class="esri-icon-map-pin"></span>
    </div>
    <div id="line-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polyline">
      <span class="esri-icon-polyline"></span>
    </div>
    <div id="polygon-button" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
      <span class="esri-icon-polygon"></span>
    </div>

    <div class="ext-box">
      <div class="int-box">
          <h2 class="boxpadding">Geometry Selection</h2>
          <span id="info"></span></br></br>
          <div class="float-container">
              <div class="float-child1">
                <div>Distance</div>
              </div>
              <div class="float-child2">
                 <select name="distance" id="distance" onchange="valDistance()" style="width:75px;">
                  <option value="1"> 1</option>
                  <option value="2"> 2</option>
                  <option value="3"> 3</option>
                  <option value="5"> 5</option>
                  <option value="10"> 10</option>
                 </select>
              </div>
          </div>
          </br>
          <div class="float-container">
              <div class="float-child1">
                <div>Measurement</div>
              </div>
              <div class="float-child2">
                 <select name="distanceType" id="distanceType" onchange="valType()" style="width:75px;">
                    <option value="miles">miles</option>
                    <option value="feet">feet</option>
                    <option value="meters">meters</option>
                 </select>
              </div>
          </div>          
          </br></br>
         <div class="boxpadding" id="infoDistance">Distance:</div>
         <span class="boxpadding" id="infoType">Type:</span></br></br>         
         <div class="menu">
              <div>
                 <div id="clear-button2" class="esri-widget esri-widget--button esri-interactive" title="Clear Grpahics">
                    <span class="esri-icon-erase"></span>
                 </div> 
                 <div id="point-button2" class="esri-widget esri-widget--button esri-interactive" title="Draw point">
                    <span class="esri-icon-map-pin"></span>
                 </div>
                 <div id="line-button2" class="esri-widget esri-widget--button esri-interactive" title="Draw polyline">
                    <span class="esri-icon-polyline"></span>
                 </div>
                 <div id="polygon-button2" class="esri-widget esri-widget--button esri-interactive" title="Draw polygon">
                   <span class="esri-icon-polygon"></span>
                 </div>
              </div>
            </div>
         </br>        
         <span id="info2" class="boxpadding">Geometry:</span></br></br>              
         <div class="FixedHeightContainer">
           <div class="header" id="header">Results</div>
           <div class="geometryResultsdiv" id="geometryResultsdiv">  </div>
         </div>
     </div> <!-- End of int box -->
    </div> <!-- End of ent box -->

  </div>
</body>

</html>

 

0 Kudos
jaykapalczynski
Frequent Contributor

@RobertScheitlin__GISP  Follow up question.... I was able to write to a global variable and get the geometry so that's all good to go... But I have been trying to get your other approach to work and have been unsuccessful...not sure how to incorporate this into my code.  Do you have any further hints?

 

A far as querying the buffer graphic. Just get the graphic from the bufferGraLayer graphics property.

let buffGeom = bufferGraLayer.graphics[0].geometry;

 

 

0 Kudos