Issue with geometryEngine.geodesicLength on spatialReference 2039

1254
2
01-14-2019 12:30 PM
YarivHabot
New Contributor

Hello,

 I'm trying to draw a polygon and get its perimeter and area. Once I'm using spatialReference 2039, the geometryEngine.geodesicLength and geometryEngine.geodesicArea methods fail with this error:

Uncaught Error: Not Implemented
at Object.d.df (VM1280 geometryEngine.js:535)
at Function.b.kc (VM1280 geometryEngine.js:1171)
at b.V (VM1280 geometryEngine.js:773)
at Function.g.PS (VM1280 geometryEngine.js:608)
at Function.d.geodesicLength (VM1280 geometryEngine.js:1275)
at createGraphic (index.html?sample=draw-line:92)
at Object.updateVertices (index.html?sample=draw-line:61)
at Object.r [as onvertex-add] (VM1269 dojo.js:60)
at Function.h.emit (VM1269 dojo.js:55)
at Function.h.emit (VM1269 dojo.js:56)

My code is based on this sample: ArcGIS API for JavaScript Sandbox and can be tested here: Draw polyline - 4.9 . The error appears once drawing begins. Following is my code. 

Can you help me out?

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">

<title>Draw polyline - 4.9</title>

<link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css">

<script src="https://js.arcgis.com/4.8/"></script>

<style>

html,

body,

#viewDiv {

height: 100%;

width: 100%;

margin: 0;

padding: 0;

}

</style>

<script>

require([

"esri/Map",

"esri/views/MapView",

"esri/views/2d/draw/Draw",

"esri/Graphic",

"esri/geometry/Polygon",

"esri/geometry/geometryEngine",

"esri/geometry/SpatialReference",

"esri/geometry/Extent",

"esri/layers/TileLayer"

], function(

Map, MapView, Draw, Graphic, Polygon, geometryEngine, SpatialReference, Extent, TileLayer

) {

const map = new Map({

basemap: "satellite"

});

const view = new MapView({

container: "viewDiv",

map: map,

spatialReference: new SpatialReference({wkid: 2039})

});

view.extent = new Extent({

xmin: 169209,

ymin: 659425,

xmax: 192454,

ymax: 672847,

spatialReference: {wkid: 2039}

});

map.layers.add(new TileLayer({ url: "http://gisn.tel-aviv.gov.il/arcgis/rest/services/IView2Ortho2017/MapServer" }));

// 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 = function() {

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

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

//var polygon = createPolygon(vertices);

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

}

var area = geometryEngine.geodesicLength(graphic.geometry, "meters");

console.log(area);

// return intersectingSegment

return {

selfIntersects: intersectingSegment

}

}

function createPolygon(vertices) {

return new Polygon({

rings: vertices,

spatialReference: view.spatialReference

});

}

// 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>

0 Kudos
2 Replies
JohnGrayson
Esri Regular Contributor

As mentioned in the help, the geometryEngine.geodesicLength() method works with 4326 and Web Mercator spatial references, and it suggests you should use geometryEngine.planarLength() instead.

jimiechaos
New Contributor

thank you 

0 Kudos