I see there is no 2d direct line measurement for 4.7. I use 2d mapview also I want a 2d direct line measurement. In api reference, it says dlm can be made by using geometryengine and draw classes. I used non-intersecting draw line. Now I want to integrate with geometryengine to measure distance but I don't know how.
Also, draw non-intersecting line not work correctly right now even in the sample. I have to double click to draw but it was working correctly before.
Using codes:
 view.when(function (evt) {
 var draw = new Draw({
 view: view
 });
// ********************
 // draw polyline button
 // ********************
 var drawLineButton = document.getElementById("meabut");
 drawLineButton.onclick = function () {
 view.graphics.removeAll();
 enableCreateLine(draw, view);
 }
 });
function enableCreateLine(draw, view) {
 // creates and returns an instance of PolyLineDrawAction
 // can only draw a line by clicking on the map
 var action = draw.create("polyline", {
 mode: "click"
 });
// focus the view to activate keyboard shortcuts for sketching
 view.focus();
// listen to vertex-add event on the polyline draw action
 action.on("vertex-add", updateVertices);
// listen to vertex-remove event on the polyline draw action
 action.on("vertex-remove", updateVertices);
// listen to cursor-update event on the polyline draw action
 action.on("cursor-update", createGraphic);
// listen to draw-complete event on the polyline draw action
 action.on("draw-complete", updateVertices);
}
// This function is called from the "vertex-add" and "vertex-remove" events. 
 
 // Checks if the last vertex is making the line intersect itself.
function updateVertices(evt) {
 // create a polyline from returned vertices
 var result = createGraphic(evt);
// if the last vertex is making the line intersects itself,
 // prevent "vertex-add" or "vertex-remove" from firing
 if (result.selfIntersects) {
 evt.preventDefault();
 }
 }
// create a new graphic presenting the polyline that is being drawn on the view
 function createGraphic(evt) {
 var vertices = evt.vertices;
 view.graphics.removeAll();
// a graphic representing the polyline that is being drawn
 var graphicc = new Graphic({
 geometry: new 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 the polyline intersects itself.
 var intersectingFeature = getIntersectingFeature(graphicc.geometry);
// Add a new graphic for the intersecting segment.
 if (intersectingFeature) {
 view.graphics.addMany([graphic, intersectingFeature]);
 }
 // Just add the graphic representing the polyline if no intersection
 else {
 view.graphics.add(graphicc);
 }
// return the graphic and intersectingSegment
 return {
 graphic: graphicc,
 selfIntersects: intersectingFeature
 }
 }
// function that checks if the line intersects itself
 function isSelfIntersecting(polyline) {
 if (polyline.paths[0].length < 3) {
 return false
 }
 var line = polyline.clone();
//get the last segment from the polyline that is being drawn
 var 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, changes the last 
 // segment's symbol giving a visual feedback to the user.
 function getIntersectingFeature(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) {
 var line = polyline.clone();
 var lastXYPoint = line.removePoint(0, line.paths[0].length - 1);
 var existingLineFinalPoint = line.getPoint(0, line.paths[0].length -
 1);
return new Polyline({
 spatialReference: view.spatialReference,
 hasZ: false,
 paths: [
 [
 [existingLineFinalPoint.x, existingLineFinalPoint.y],
 [lastXYPoint.x, lastXYPoint.y]
 ]
 ]
 });
 }
Solved! Go to Solution.
Kutay,
Here are the changes to make your code work:
...
        // check the polyline intersects itself.
        var intersectingFeature = getIntersectingFeature(graphicc.geometry);
        var lengthh = geometryEngine.planarLength(graphicc.geometry, "kilometers");
        labelAreas(graphicc, lengthh);
        console.log(lengthh, "km");
...
        function labelAreas(geom, area) {
          var graph = new Graphic({
            geometry: geom.geometry.extent.center,
            symbol: {
              type: "text",
              color: "black",
              haloColor: "black",
              haloSize: "1px",
              text: area.toFixed(2) + " km",
              xoffset: 3,
              yoffset: 3,
              font: { // autocast as Font
                size: 14,
                family: "sans-serif"
              }
            }
          });
          view.graphics.add(graph);
          // console.log(area);
          console.log(geom);
        }
...Kutay,
You just use the geodesicLength or planarLength methods in the geometryEngibe class.
Thanks. I want to text on top of drawing like in these example.
Measure while drawing | ArcGIS API for JavaScript 4.7
I did the source code like this but I couldn't show distance as text on the line vertice.
view.when(function (evt) {
 var draw = new Draw({
 view: view
 });
// ********************
 // draw polyline button
 // ********************
 var drawLineButton = document.getElementById("meabut");
 drawLineButton.onclick = function () {
 view.graphics.removeAll();
 enableCreateLine(draw, view);
 
 
 }
 });
function enableCreateLine(draw, view) {
 // creates and returns an instance of PolyLineDrawAction
 // can only draw a line by clicking on the map
 var action = draw.create("polyline", {
 mode: "click"
 });
// focus the view to activate keyboard shortcuts for sketching
 view.focus();
// listen to vertex-add event on the polyline draw action
 action.on("vertex-add", updateVertices);
// listen to vertex-remove event on the polyline draw action
 action.on("vertex-remove", updateVertices);
// listen to cursor-update event on the polyline draw action
 action.on("cursor-update", createGraphic);
// listen to draw-complete event on the polyline draw action
 action.on("draw-complete", updateVertices);
}
// This function is called from the "vertex-add" and "vertex-remove" events. 
 
 // Checks if the last vertex is making the line intersect itself.
function updateVertices(evt) {
 // create a polyline from returned vertices
 var result = createGraphic(evt);
// if the last vertex is making the line intersects itself,
 // prevent "vertex-add" or "vertex-remove" from firing
 if (result.selfIntersects) {
 evt.preventDefault();
 }
 }
// create a new graphic presenting the polyline that is being drawn on the view
 function createGraphic(evt) {
 var vertices = evt.vertices;
 view.graphics.removeAll();
// a graphic representing the polyline that is being drawn
 var graphicc = new Graphic({
 geometry: new 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 the polyline intersects itself.
 var intersectingFeature = getIntersectingFeature(graphicc.geometry);
 var lengthh = geometryEngine.planarLength(graphicc.geometry, "kilometers");
 labelAreas(graphicc, length);
 console.log(lengthh, "km");
 
 // Add a new graphic for the intersecting segment.
 if (intersectingFeature) {
 view.graphics.addMany([graphicc, intersectingFeature]);
 }
 // Just add the graphic representing the polyline if no intersection
 else {
 view.graphics.add(graphicc);
 }
// return the graphic and intersectingSegment
 return {
 graphic: graphicc,
 selfIntersects: intersectingFeature
 }
function labelAreas(geom, area) {
 var graph = new Graphic({
 geometry: geom.geometry,
 symbol: {
 type: "text",
 color: "black",
 haloColor: "black",
 haloSize: "1px",
 text: area.toFixed(2) + " km",
 xoffset: 3,
 yoffset: 3,
 font: { // autocast as Font
 size: 14,
 family: "sans-serif"
 }
 }
 });
 view.graphics.add(graphicc);
 // console.log(area);
 console.log(geom);
 }
 
 }
Kutay,
Please provide a full sample for testing.
Here is my full code
Kutay,
Here are the changes to make your code work:
...
        // check the polyline intersects itself.
        var intersectingFeature = getIntersectingFeature(graphicc.geometry);
        var lengthh = geometryEngine.planarLength(graphicc.geometry, "kilometers");
        labelAreas(graphicc, lengthh);
        console.log(lengthh, "km");
...
        function labelAreas(geom, area) {
          var graph = new Graphic({
            geometry: geom.geometry.extent.center,
            symbol: {
              type: "text",
              color: "black",
              haloColor: "black",
              haloSize: "1px",
              text: area.toFixed(2) + " km",
              xoffset: 3,
              yoffset: 3,
              font: { // autocast as Font
                size: 14,
                family: "sans-serif"
              }
            }
          });
          view.graphics.add(graph);
          // console.log(area);
          console.log(geom);
        }
...Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
