Select to view content in your preferred language

Does ignoreInvalidLocations work for Non-traversable network element?

475
1
09-20-2023 12:22 AM
LeoDeng
Frequent Contributor

Hi All,

    When solving the route problem with ArcGIS Map SDKs for JavaScript 4.27, I got an unexplained result. There are 3 stops on the map and the 2nd stop should be a non-traversable network element position. However, the api returns the response with a route which curb approach is incorrect for 2nd stop.

 

<!DOCTYPE html lang="en">
  <head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
  <title>Network Invalid Location</title>
  
  <style>
    html,
    body,
    #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; };
  </style>
  <link rel="stylesheet" href="https://js.arcgis.com/4.27/esri/themes/light/main.css">
  <style>
    /* overwrite esri default css */
    .esri-view .esri-view-surface--inset-outline:focus::after {
      outline: none;
    };
  </style>
  <script src="https://js.arcgis.com/4.27/"></script>
  <script>
    require([
      "esri/config", "esri/intl", "esri/Map", "esri/views/MapView", "esri/geometry/Point", "esri/geometry/Polyline",
      "esri/symbols/SimpleLineSymbol", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/rest/support/FeatureSet",
      "esri/symbols/PictureMarkerSymbol", "esri/rest/route", "esri/rest/support/RouteParameters"],
    function(
      esriConfig, esriIntl, Map, MapView, Point, Polyline,
      SimpleLineSymbol, Graphic, GraphicsLayer, FeatureSet,
      PictureMarkerSymbol, route, RouteParameters) {

      esriConfig.apiKey = "<YOUR_API_KEY>";

      esriIntl.setLocale("en");

      let _map, _stopLayer, _routeLayer;
      let _stop1, _stop2, _stop3;

      const CURB_APPROACH = {
        EITHER_SIDE: 0,
        RIGHT_SIDE: 1,
        LEFT_SIDE: 2,
        NO_U_TURN: 3
      };

      const initMap = () =>
      {
        _map = new Map({
          basemap: "arcgis-streets" // Basemap layer service
        });

        const CREEK_VIEW_PLZ = [-77.519510, 39.042121];
        const CONSTRAINT_EXTENT = {
          type: "extent",
          xmin: -180,
          ymin: -70,
          xmax: 180,
          ymax: 70
        };

        const view = new MapView({
          map: _map,
          center: CREEK_VIEW_PLZ,
          constraints: {
            geometry: CONSTRAINT_EXTENT,
            minZoom: 3,
            maxZoom: 18
          },
          zoom: 16, // Zoom level
          container: "viewDiv" // Div element
        });

        _stopLayer = new GraphicsLayer({ id: "stop-layer" });
        _routeLayer = new GraphicsLayer({ id: "route-layer" });

        _map.addMany([_routeLayer, _stopLayer]);
      };

      const stopSymbol = (sequence) =>
      {
        const svgString = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="28" height="28">' +
          '<g>' +
          '<circle r="12" cy="14" cx="14" stroke-linecap="butt" stroke="#000000" stroke-width="2" fill="#0000FF" />' +
          `<text text-anchor="middle" font-size="12" x="50%" y="50%" dy=".3em" stroke-width="0" fill="#FFFFFF" >${sequence}</text>` +
          '</g>' +
          '</svg >';
        const svg = `data&colon;image/svg+xml;charset=UTF-8;base64,${btoa(svgString)}`;
        return new PictureMarkerSymbol({ url: svg, height: 28, width: 28 });
      };

      const createStopGraphic = (location, sequence, curbApproach) =>
      {
        const { longitude, latitude } = location;
        const geometry = new Point({
          type: "point",
          x: longitude,
          y: latitude
        });
        const symbol = stopSymbol(sequence);
        const attributes = {
          CurbApproach: curbApproach,
          Name: sequence,
          Sequence: sequence
        };

        const graphic = new Graphic({ geometry, symbol, attributes });
        return graphic;
      };

      const addStops = () =>
      {
        const location1 = { longitude: -77.520401, latitude: 39.043210 };
        const location2 = { longitude: -77.5201, latitude: 39.0411 };
        const location3 = { longitude: -77.518320, latitude: 39.042180 };

        _stop1 = createStopGraphic(location1, 1, CURB_APPROACH.RIGHT_SIDE);

        // curb approach is left side. This should be a non-traversable network element position.
        _stop2 = createStopGraphic(location2, 2, CURB_APPROACH.LEFT_SIDE);
        
        _stop3 = createStopGraphic(location3, 3, CURB_APPROACH.RIGHT_SIDE);

        _stopLayer.addMany([_stop1, _stop2, _stop3]);
      };

      const calculateRoute = async () =>
      {
        const url = "https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";
        const defaultParameters = {
          directionsLengthUnits: "kilometers",
          findBestSequence: false,
          ignoreInvalidLocations: false,  // expectation: get errors when there are invalid stops.
          impedanceAttribute: null,
          outputGeometryPrecision: 0,
          outputGeometryPrecisionUnits: "feet",
          outputLines: "true-shape",
          outSpatialReference: "102100",
          pointBarriers: null,
          polylineBarriers: null,
          polygonBarriers: null,
          preserveFirstStop: true,
          preserveLastStop: true,
          restrictionAttributes: [],
          restrictUTurns: "at-dead-ends-only",
          returnBarriers: false,
          returnDirections: true,
          returnPolygonBarriers: false,
          returnPolylineBarriers: false,
          returnPointBarriers: false,
          returnTraversedEdges: false,
          returnTraversedJunctions: false,
          returnTraversedTurns: false,
          returnRoutes: true,
          returnStops: true,
          returnZ: false,
          startTime: new Date()
        };

        const featureSet = new FeatureSet({ features: [_stop1, _stop2, _stop3]});
        const parameters = {
          stops: featureSet
        };

        const params = Object.assign({}, defaultParameters, parameters);
        const routeParameters = new RouteParameters(params);

        return route.solve(url, routeParameters).then((response) => {
          results = response?.routeResults[0];
          return results;
        }).catch((error) => {
          console.log(error);
        });
      };

      const addRoutes = (routeResults) =>
      {
        const route = routeResults.route;
        route.symbol = {
          type: "simple-line",
          style: "solid",
          color: "#0000FF",
          width: 5
        };

        _routeLayer.add(route);
      };


      initMap();
      addStops();

      calculateRoute().then((routeResults) =>
      {
        addRoutes(routeResults);
      });
  
    });
  </script>

  </head>
  <body>
  <div id="viewDiv"></div>
  </body>
</html>

 


attention: the curb approach for 2nd stop is 2 (left-side).

LeoDeng_1-1695194303689.png

 



This is the result shows in ArcMap 10.8.1

LeoDeng_0-1695193368742.png

Is there any missing parameters in solving the problem?

Addition Information:
The response from https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve shows the curb approach is 2 (Left side)

LeoDeng_0-1695198265630.png

Does it make sense?


Thanks,
Leo

0 Kudos
1 Reply
LeoDeng
Frequent Contributor

Is there any information for this issue?

0 Kudos