Arcgis Api for JS Sample Code 学习记录(2)

397 阅读1分钟

Demo2  draw-line

<!DOCTYPE html>
<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.22</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.22/"></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"
  ], (Map, MapView, Draw, Graphic, geometryEngine) => {
    const map = new Map({
      basemap: "gray-vector"
    });

    const view = new MapView({
      container: "viewDiv",
      map: map,
      zoom: 15,
      center: [18.06, 59.34]
    });

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

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

    // draw polyline button
    document.getElementById("line-button").onclick = () => {
      view.graphics.removeAll();

      // 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"
        ],
        updateVertices
      );
    };

    // Checks if the last vertex is making the line intersect itself.
    function updateVertices(event) {
      // create a polyline from returned vertices
      if (event.vertices.length > 1) {
        const result = createGraphic(event);

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

    // create a new graphic presenting the polyline that is being drawn on the view
    function createGraphic(event) {
      const vertices = event.vertices;
      view.graphics.removeAll();

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

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

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

      // 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]
          ]
        ]
      };
    }
  });
</script>
  </head>

  <body>
    <div id="viewDiv">
      <div id="line-button" class="esri-widget esri-widget--button
        esri-interactive" title="Draw polyline">
        <span class="esri-icon-polyline"></span>
      </div>
    </div>
  </body>
</html>

效果预览图

image.png

分析

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

构造一个Draw实例


      // 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"
        ],
        updateVertices
      );
    };

    // Checks if the last vertex is making the line intersect itself.
    function updateVertices(event) {
      // create a polyline from returned vertices
      if (event.vertices.length > 1) {
        const result = createGraphic(event);

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

官网例子:

// create a new instance of draw
let draw = new Draw({
  view: view
});

// create an instance of draw polyline action
// the polyline vertices will be only added when
// the pointer is clicked on the view
let action = draw.create("polyline", {mode: "click"});

// fires when a vertex is added
action.on("vertex-add", function (evt) {
  measureLine(evt.vertices);
});

// fires when the pointer moves
action.on("cursor-update", function (evt) {
  measureLine(evt.vertices);
});

// fires when the drawing is completed
action.on("draw-complete", function (evt) {
  measureLine(evt.vertices);
});

// fires when a vertex is removed
action.on("vertex-remove", function (evt) {
  measureLine(evt.vertices);
});

function measureLine(vertices) {
  view.graphics.removeAll();

  let line = createLine(vertices);
  let lineLength = geometryEngine.geodesicLength(line, "miles");
  let graphic = createGraphic(line);
  view.graphics.add(graphic);
}

function createLine(vertices) {
  let polyline = {
    type: "polyline", // autocasts as new Polyline()
    paths: vertices,
    spatialReference: view.spatialReference
  }
  return polyline;
}

相关API解释见此链接:developers.arcgis.com/javascript/…

image.png

结合官网解释和示例代码,这段sourcecode表示,action实例监听了vertex-add、cursor-update、draw-complete、vertex-remove、redo和undo行为,并执行updateVertices方法 将代码改为

// creates and returns an instance of PolyLineDrawAction
const action = draw.create("polygon", { mode: "hybrid" });

效果如下,既能点击又能拖拽:

image.png


        // create a new graphic presenting the polyline that is being drawn on the view
        function createGraphic(event) {
          debugger;
          const vertices = event.vertices;
          view.graphics.removeAll();

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

针对这段代码,阅读了官网上Graphics的教程: developers.arcgis.com/javascript/…