PTV Developer / Routing API - how to determine distance per country?

Deals with generic topics such as logging, framework and so on. If you are not sure where to place your topic just put it here.
Post Reply
User avatar
Bernd Welter
Site Admin
Posts: 2574
Joined: Mon Apr 14, 2014 10:28 am
Contact:

PTV Developer / Routing API - how to determine distance per country?

Post by Bernd Welter »

I've been asked how I'd recommend to compute the "distance per country" in a PTV Developer Routing API client application (as this info is not native part of the response).
PTV Developer.distancePerCountry.png
Here's my approach - based on Border_Events and Waypoint_Events.
Feedback is welcome - especially if you detect an error ;-)

Code: Select all

       
// for a proper aggregation of country-wise data we need to use BORDER_EVENTS and WAYPOINT_EVENTS
if ((results.Contains(Routing.Model.Results.BORDER_EVENTS)) && (results.Contains(Routing.Model.Results.WAYPOINT_EVENTS)))
{                        
    Dictionary<string, double> dictDistancePerCountry = new Dictionary<string, double>();
    List<Routing.Model.Event> lstWaypointEvents = lstEvents.Where(ev => ev.Waypoint != null).ToList();
    Routing.Model.Event firstWaypoint = lstWaypointEvents.First(), lastWaypoint = lstWaypointEvents.Last();
    // convenience method : in some countries like "US" we use a combined string such as "US-CA" to refer to a subunit.
    string getCountry(Routing.Model.Event ev)
    {
        return ev.CountryCode.Split('-')[0];
    }
    // are there any border crossings?
    if (lstEvents.Any(ev => ev.Border != null))
    {
        List<Routing.Model.Event> lstBorderEvents = lstEvents.Where(ev => ev.Border != null).ToList();
        Routing.Model.Event firstBorder = lstBorderEvents.First() , lastBorder = lstBorderEvents.Last();
        dictDistancePerCountry.Add(getCountry( firstWaypoint ), firstBorder.DistanceFromStart);
        double lastPart = lastWaypoint.DistanceFromStart - lastBorder.DistanceFromStart;
        
        if (dictDistancePerCountry.ContainsKey(getCountry( lastBorder)))
            dictDistancePerCountry[getCountry(lastBorder)] += lastPart;
        else
            dictDistancePerCountry.Add(getCountry(lastBorder), lastPart);
        for (int index = 1; index < lstBorderEvents.Count; index++)
        {
            double leg = lstBorderEvents[index].DistanceFromStart - lstBorderEvents[index - 1].DistanceFromStart;
            string country = getCountry(lstBorderEvents[index-1]);
            if (dictDistancePerCountry.ContainsKey(country))
                dictDistancePerCountry[country] += leg;
            else
                dictDistancePerCountry.Add(country, leg);
        }
    }
    else // no border crossings
    {
        dictDistancePerCountry.Add(getCountry(lastWaypoint), lastWaypoint.DistanceFromStart);
    }
    // visualization of aggregates.
    chartRouting_CustomAGgregates_DistancePerCountry.Series.First().Points.Clear();
    foreach (string key in dictDistancePerCountry.Keys)
    {
        string label = "Country=" + key + "\r\ndistance=" + Tools.displayDistance(dictDistancePerCountry[key], routeResponse.Distance);
        DataPoint dataPoint = new DataPoint { 
            ToolTip = label,
            Label = label,
            YValues = new double[] { dictDistancePerCountry[key] }
        };
        chartRouting_CustomAGgregates_DistancePerCountry.Series.First().Points.Add(dataPoint);
    }
    foreach (DataPoint dp in chartRouting_CustomAGgregates_DistancePerCountry.Series.First().Points)
    { 
        dp.Color = System.Drawing.Color.FromArgb(128,dp.Color);
    }
    dgvRouting_CustomAGgregates_DistancePerCountry.DataSource = dictDistancePerCountry.Keys.Select(k => new {
        k,
        distance = dictDistancePerCountry[k],
        RelativeDistance = Tools.displayDistance(dictDistancePerCountry[k], routeResponse.Distance)
    }).ToArray();
}

Bernd Welter
Technical Partner Manager Developer Components
PTV Logistics - Germany

Bernd at... The Forum,LinkedIn, Youtube, StackOverflow
I like the smell of PTV Developer in the morning... :twisted:
Post Reply