Text Symbol is not working

1027
2
12-11-2019 09:25 PM
kawishabbas
Occasional Contributor

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>
0 Kudos
2 Replies
UndralBatsukh
Esri Regular Contributor

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

kawishabbas
Occasional Contributor

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? 

0 Kudos