Hi,
I want to add length measurement on polyline graphic for that i use text symbol but its not working.Following is the sample code.
<!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.13</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.12/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.12/"></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/projection",
"esri/geometry/SpatialReference"
], function(Map, MapView, Draw, Graphic, geometryEngine,projection, SpatialReference) {
projection.load()
let cs1 = new SpatialReference({
wkid: 4326 //PE_GCS_ED_1950
})
const map = new Map({
basemap: "satellite"
});
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 12,
center: [67.060943, 24.837139]
});
// 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) {
let result
// create a polyline from returned vertices
if (event.vertices.length > 1) {
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();
let polyline = {
type: "polyline",
paths: vertices,
spatialReference: view.spatialReference
}
// a graphic representing the polyline that is being drawn
const graphic = new Graphic({
geometry:polyline ,
symbol: {
type: "simple-line", // autocasts as new SimpleFillSymbol
color: [4, 90, 141],
width: 4,
cap: "round",
join: "round"
}
});
var polylineLength = geometryEngine.geodesicLength(graphic.geometry, "meters");
if (polylineLength < 0) {
// simplify the polygon if needed and calculate the polylineLength again
var simplifiedPolygon = geometryEngine.simplify(graphic.geometry);
if (simplifiedPolygon) {
polylineLength = geometryEngine.geodesicLength(simplifiedPolygon, "meters");
}
}
length.innerHTML = polylineLength.toFixed(4) + "meter"
let textSymbol = {
type: "text", // autocasts as new TextSymbol()
color: "white",
haloColor: "black",
haloSize: 2,
text: polylineLength.toFixed(4) + "meter",
xoffset: 3,
yoffset: 3,
font: { // autocasts as new Font()
size: 8,
family: "sans-serif",
weight: "bold"
}
}
let graphicLabel = new Graphic({
geometry: polyline,
//attributes: item.attributes,
symbol: textSymbol,
})
view.graphics.add(graphicLabel)
// 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
};
// start displaying the area of the polygon
}
// 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>
Hi there,
It is not working because TextSymbol can only be used to symbolize point geometries. Looks like your graphic has polyline geometry and textsymbol. It wont work. Instead you can get one of the vertices from your polyline and assign this vertex as a point geometry to your graphic.
This app here shows the area of a polygon. The area is displayed at the center of the polygon.
Hope this helps,
-Undral
Thanks Undral Batsukh
Its working now, but still i have a problem that the textsymbol is not parallel to line feature can you please guide me how we can align text symbol?