[GIS] How to change a GraphicsLayer’s geometry in the ArcGIS API for Javascript 4.0

arcgis-javascript-api

The setup:

  • Creating a Point with a longitude and latitude
  • Creating a SimpleMarkerSymbol
  • Creating a Graphic using the Point and SimpleMarkerSymbol
  • Adding the Graphic to the view's graphics

What's I'm trying to do:

  • Change the point's latitude and longitude
  • Have this change be reflected in the map.

What I've tried:

  • Just changing the point's latitude and longitude.
  • Removing the Graphic with the point, then changing the latitude and longitude, then adding the graphic back to the view.
  • Looking through the ArcGIS API reference for Javascript 4.0 for anything like refresh/update/redraw/… on Map objects, MapView objects, and GraphicsLayer objects

Some sample code to play with:

I took the following from an ArcGIS example and modified it to show as simply as possible what I'm trying to do.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Get started with graphics - 4.0</title>

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

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/Graphic",
      "esri/geometry/Point",
      "esri/symbols/SimpleMarkerSymbol",
      "dojo/domReady!"
    ], function(
      Map, MapView,
      Graphic, Point,
      SimpleMarkerSymbol
    ) {

      var map = new Map({
        basemap: "hybrid"
      });

      var view = new MapView({
        center: [-80, 35],
        container: "viewDiv",
        map: map,
        zoom: 3
      });

      /**********************
      * Create a point graphic
      **********************/

      // First create a point geometry (this is the location of the Titanic)
      var point = new Point({
        longitude: -49.97,
        latitude: 41.73
      });

      // Create a symbol for drawing the point
      var markerSymbol = new SimpleMarkerSymbol({
        color: [226, 119, 40],
        outline: { // autocasts as new SimpleLineSymbol()
          color: [255, 255, 255],
          width: 2
        }
      });

      // Create a graphic and add the geometry and symbol to it
      var pointGraphic = new Graphic({
        geometry: point,
        symbol: markerSymbol
      });

      // Add the graphics to the view's graphics view
      view.then(function() {
        view.graphics.add(pointGraphic);
      });

      //***THIS IS THE FUNCTION I'M TRYING TO GET WORKING***
      var movePoint = function (lat, lon) {
        point.latitude = lat;
        point.longitude = lon;
        //What should go here to update the map?
      };

      document.getElementById("movePoint").onclick = function () { movePoint(0,0); };
    });
  </script>
</head>

<body>
  <button id="movePoint">Move Point to 0,0</button>
  <div id="viewDiv"></div>
</body>

</html>

Best Answer

I was able to to get this to work with the following code.

var movePoint = function (lat, lon) {
  view.graphics.remove(pointGraphic);
  point.latitude = lat;
  point.longitude = lon;
  pointGraphic = new Graphic({
    geometry: point,
    symbol: markerSymbol
  });
  view.graphics.add(pointGraphic);
};

It seems like the trick here to get it to work is the creation of the new Graphic. As long as I was referencing the old Graphic object, even if I had changed all of the properties on it, the map view was not updating with those new properties.

I'm still interested in seeing if there are better solutions out there, but for now this looks like what needs to be done.