2d direct line measurement for 4.7?

1955
6
Jump to solution
04-27-2018 05:37 AM
KutayDeril
New Contributor II

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

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Kutay,

   Here are the changes to make your code work:

  1. line 5 below your length needs to be lengthh.
  2. line 10 your geometry needs to be geometry: geom.geometry.extent.center.
  3. line 25 view.graphics.add(graph);
...
        // 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);
        }
...

View solution in original post

6 Replies
KutayDeril
New Contributor II

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);
}

}

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Kutay,

  Please provide a full sample for testing.

0 Kudos
KutayDeril
New Contributor II

Paste ofCode 

Here is my full code

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Kutay,

   Here are the changes to make your code work:

  1. line 5 below your length needs to be lengthh.
  2. line 10 your geometry needs to be geometry: geom.geometry.extent.center.
  3. line 25 view.graphics.add(graph);
...
        // 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);
        }
...
RobertScheitlin__GISP
MVP Emeritus

Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.

0 Kudos