Select to view content in your preferred language

Arcgis Javascript 4.17 how to create a pointer to move in smooth way like google maps

676
3
03-30-2023 01:18 AM
IshamFazal
New Contributor

My goal is to move a pointer from one geo location to another based on the GPS location received from the device. however, i managed to do this by clearing the layer and re drawing the point on the map. but in a graphical prospective I need to move the pointer in a smooth way rather than clearing out the point and readding it to the maps. this application is related to fleet. 

It would be great if someone could point me on the right direction on this.

im using Arcgis 4.17 Javascript API

 

 

0 Kudos
3 Replies
JamesIng
Regular Contributor

You can use the mapview.goTo() method to animate from one location to another - supplying the new GPS location as the target.

James from www.landkind.com
0 Kudos
IshamFazal
New Contributor

mapview.goTo() this method is used to navigate from 1 point to another. that's not what I am looking for. actually im looking for something like this.

I need the point to be moved from 1 location to another without clearing the mapview and readding the point. I need to move the point by animating it

 

basically a fleet moving on the street. that's the whole goal

 

0 Kudos
JamesIng
Regular Contributor

Thanks for clarifying - unfortunately I dont think there's any way to animate something in the framework without clearing and readding it - as effectively you need to redraw the frame for it to animate.

The smoothness comes into how often you update the frame and how far you're moving the point.

If you simply animating from one co-ordinate from another you can just calculate the steps inbetween the two endpoints and then remove and add a point to the new step.

If it's along a route you'll need to calculate the route and likely densify the results so you have more steps to animate through.

 This is rough example based on the sample code, after you click two points on the map it draws a new symbol and clears and adds the point along the path effectively animating it.

To get even more smooth results you'd probably increase the density and decrease the time between updates.

<!-- 

To run this demo, you need to replace 'YOUR_API_KEY' with an API key from the ArcGIS Developers dashboard.

Sign up for a free account and get an API key.

https://developers.arcgis.com/documentation/mapping-apis-and-services/get-started/

 -->
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Route | Sample | ArcGIS Maps SDK for JavaScript 4.26</title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #paneDiv {
        position: absolute;
        top: 10px;
        left: 62px;
        padding: 0 12px 0 12px;
        background-color: rgba(0, 0, 0, 0.5);
        color: white;
      }
    </style>

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

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/Graphic",
        "esri/layers/GraphicsLayer",
        "esri/rest/route",
        "esri/rest/support/RouteParameters",
        "esri/rest/support/FeatureSet",
        "esri/geometry/geometryEngine"
      ], function (
        Map,
        MapView,
        Graphic,
        GraphicsLayer,
        route,
        RouteParameters,
        FeatureSet,
        geometryEngine
      ) {
        // Point the URL to a valid routing service
        const routeUrl =
          "https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";

        // The stops and route result will be stored in this layer
        const routeLayer = new GraphicsLayer();
        const pinLayer = new GraphicsLayer();
        let routeShowing = false;
        let index = 0;
        let routeResult = null


        // Setup the route parameters
        const routeParams = new RouteParameters({
          // An authorization string used to access the routing service
          apiKey: "%YOUR_API_KEY%",
          stops: new FeatureSet(),
          outSpatialReference: {
            // autocasts as new SpatialReference()
            wkid: 3857
          }
        });

        // Define the symbology used to display the stops
        const stopSymbol = {
          type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
          style: "cross",
          size: 15,
          outline: {
            // autocasts as new SimpleLineSymbol()
            width: 4
          }
        };

        const pinSymbol = {
          type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
          style: "circle",
          size: 10,
          outline: {
            // autocasts as new SimpleLineSymbol()
            width: 6
          }
        };

        // Define the symbology used to display the route
        const routeSymbol = {
          type: "simple-line", // autocasts as SimpleLineSymbol()
          color: [0, 0, 255, 0.5],
          width: 5
        };

        const map = new Map({
          basemap: "streets-navigation-vector",
          layers: [routeLayer, pinLayer] // Add the route layer to the map
        });

        const view = new MapView({
          container: "viewDiv", // Reference to the scene div created in step 5
          map: map, // Reference to the map object created before the scene
          center: [-117.195, 34.057],
          zoom: 13
        });

        // Adds a graphic when the user clicks the map. If 2 or more points exist, route is solved.
        view.on("click", addStop);

        function addStop(event) {
          // Add a point at the location of the map click
          const stop = new Graphic({
            geometry: event.mapPoint,
            symbol: stopSymbol
          });

          routeLayer.add(stop);

          // Execute the route if 2 or more stops are input
          routeParams.stops.features.push(stop);
          if (routeParams.stops.features.length >= 2) {
            route.solve(routeUrl, routeParams).then(showRoute);
          }
        }
        // Adds the solved route to the map as a graphic
        function showRoute(data) {
          routeResult = data.routeResults[0].route;
          routeResult.geometry = geometryEngine.densify(routeResult.geometry, 25);
          routeResult.symbol = routeSymbol;
          routeLayer.add(routeResult);
          const pinPoint = new Graphic({
            geometry: {
             x:  routeResult.geometry.paths[0][0][0],
             y:  routeResult.geometry.paths[0][0][1],
             spatialReference: view.spatialReference,
             type: "point"
            },
            symbol: pinSymbol
          });
          pinLayer.add(pinPoint);
          routeShowing = true;

        }
        
        view.when(() => {
          
          let timerControl = setInterval(() => {
            if(routeShowing === true && index < routeResult.geometry.paths[0].length ) {
              index++;
              pinLayer.removeAll();
              const pinPoint = new Graphic({
            geometry: {
            x:  routeResult.geometry.paths[0][index][0],
            y:  routeResult.geometry.paths[0][index][1],
            spatialReference: view.spatialReference,
            type: "point"
            },
            symbol: pinSymbol
          });
          pinLayer.add(pinPoint);
            
            }
          }, 60);
        })
      });
    </script>
  </head>
  <body>
    <div id="viewDiv"></div>
    <div id="paneDiv" class="esri-widget">
      <div>
        <p>
          Click on the map to add stops to the route. The route from the last
          stop to the newly added stop is calculated. If a stop is not
          reachable, then the last valid point is set as the starting point.
        </p>
      </div>
    </div>
  </body>
</html>



James from www.landkind.com
0 Kudos