0

Basically I am trying to zoom to certain route segment when getting direction on OneMap. Here is the JavaScript codes where I trying to plot a route and zoom to certain route segment:

function getDirections() {
var routeData = new Route;
var from = document.getElementById('txtFrom').value
var to = document.getElementById('txtTo').value
//Draw out the line from the cordinate to another cordinate
routeData.routeStops = from + ";" + to;

//What type of mode will it do
routeData.routeMode = "DRIVE";
//can draw out untill the following coordiante
routeData.barriers = '36908.388637,35897.420831';
{
    if (document.getElementById('CbAvoid').checked) {
        routeData.avoidERP = "1";
    }
    else
        routeData.avoidERP = "0";
}
routeData.GetRoute(showRouteData)
}

function showRouteData(routeResults) {
    if (routeResults.results == "No results") {
        alert("No Route found, please try other location.")
        return
    }
    $('#divComputedDirection').show();
    directions = routeResults.results.directions[0];
    directionFeatures = directions.features;
    var routeSymbol = new esri.symbol.SimpleLineSymbol().setColor(new dojo.Color([0, 0, 255, 0.5])).setWidth(4);
    var mergedGeometry = new esri.geometry.Polyline()

    mergedGeometry.addPath(routeResults.results.routes.features[0].geometry.paths[0])
    OneMap.map.graphics.add(new esri.Graphic(mergedGeometry, routeSymbol));
    //Display the total time and distance of the route                   
    var htmlStr = "";
    htmlStr += "<img class='close-image' onclick='closeDirectionResultDIV();' alt='close' src='img/closeDirectionResult.png' />";
    htmlStr += "<span style='font-weight:bold;'><br /> &nbsp; Total distance: " + Math.round(directions.summary.totalLength) + "km" + "<br /> &nbsp; Total time: " + Math.round(directions.summary.totalTime) + "mins <br/></span>";

    document.getElementById("divComputedDirection").innerHTML = htmlStr;

    //List the directions and create hyperlinks for each route segment
    for (var i = 0; i < directions.features.length; i++) {
        var feature = directions.features[i]
        document.getElementById("divComputedDirection").innerHTML += '<a href="JavaScript:zoomToSegment(' + i + ')" style="font-size: 11px"><br>' + parseInt(parseInt(i) + 1) + ". " + feature.attributes.text + " (" + formatDistance(feature.attributes.length, "miles") + ", " + formatTime(feature.attributes.time) + ") " + '</a>';
    }
}

//Zoom to the appropriate segment when the user clicks a hyperlink in the directions list
function zoomToSegment(index) {
var segment = directionFeatures[index];
map.setExtent(segment.geometry.getExtent(), true);
if (!segmentGraphic) {
    segmentGraphic = map.graphics.add(new esri.Graphic(segment.geometry, segmentSymbol));
}
else {
    segmentGraphic.setGeometry(segment.geometry);
}

}

It did plot the route and show all the directions. But when I click on certain direction and zoom to segement, it throws me an error message which is Uncaught TypeError: Cannot call method 'getExtent' of undefined.

I wonder why is it so. Thanks in advance.

Vikash Pandey
  • 5,407
  • 6
  • 41
  • 42
  • Any clues to solve this? –  Jun 09 '14 at 05:33
  • Where do you define `directionFeatures`? If you're not defining it outside the `showRouteData()` function, then it's a local variable to that function - when the event handler triggers `zoomToSegment` then `directionFeatures` no longer exists. – Juffy Jun 10 '14 at 02:16
  • @Juffy I defined it as a global variable. Do you have any idea to solve this? –  Jun 10 '14 at 02:32
  • Not without seeing a working example, no - I would fire up a debugger (eg. Chrome's F12 dev tools) and have a look at what's in your `directionFeatures` array when the `zoomToSegment` function executes. – Juffy Jun 10 '14 at 04:30
  • @Juffy It return me an Object with the attributes of ETA: -2209161600000 length: 0.1689308050723526 maneuverType: "esriDMTTurnRight" text: "Turn right at TIONG POH ROAD to stay on TIONG BAHRU ROAD" time: 0.25339999999999996. What does the getExtent() do actually? and segment.geometry returns me an undefined. –  Jun 10 '14 at 05:16

1 Answers1

0

The root cause of your error is that you're trying to get the extent of a .geometry property that doesn't exist - that part is relatively easy. The problem, I think, is that you're looking for the geometry of each segment of the journey, and the return from OneMap's RouteTask doesn't give you that directly.

The geometry from the entire route is in

routeResults.results.routes.features[0].geometry.paths[0]

and the individual segments are in one of ESRI's fun compressed formats in the value:

routeResults.results.directions[x].features[y].compressedGeometry

There's some documentation and C# code for this compressed format here:

http://resources.esri.com/help/9.3/arcgisengine/ArcObjects/esrinetworkanalyst/INACompactStreetDirection_CompressedGeometry.htm

It should be relatively easy to port that C# code to JS if you really need the geometry of individual segments.

OneMap have a full working example here which shows how to process the results from the RouteTask, but unfortunately they don't attempt to extract the compressedGeometry field.


Edit: More sample code from ESRI here, with examples in C#/Java/Python.
Juffy
  • 1,220
  • 13
  • 22
  • As in the code to solve this problem. Because from the documentation you provided, I have no idea how to extract the compressedGeometry field. –  Jun 10 '14 at 06:39
  • I'll have a crack at porting that C# code when I get a chance, and update my answer. – Juffy Jun 10 '14 at 07:02
  • Basically I just convert all the code in Program.cs from the link you provided into JavaScript. Then, I will pass the segment into CreatePathFromCompressedGeometry(). Am I nearly there or? –  Jun 10 '14 at 07:13
  • That's the idea - that should give you a `Path` you can add to a `Polyline` and away you go. – Juffy Jun 10 '14 at 07:18
  • But do you have any idea to convert C# code into JavaScript? Because when I tried to convert, there's some error. –  Jun 10 '14 at 07:19
  • Any ideas to fix this? –  Jun 13 '14 at 01:11
  • Port of C# code into typescript: https://gist.github.com/ca0v/6a09c2fe6dfdfc0f5192 – Corey Alix Jan 04 '16 at 17:44