Hands On

Explore Custom Locations With the HERE Fleet Telematics APIs — Part II

By Shruti Kuber | 08 July 2019

In Part I of our tutorial, we learnt how to add private warehouses to a map. No one else has access to them except you. But do you really have access to them? Let's explore how to get to these custom locations further. Last time we discussed how to add, append, delete and update custom locations to your map. In Part II we will explore searching and routing to these locations within a fixed radius, within a bounding box, and along an isoline.

Within a radius

Normally, to look for places within a radius, you would need your exact location in terms of latitude and longitude and the radius of search in meters. We have already done this while using the Places > Search API How is this different from custom locations? Not by much. The only difference here is that you would search within the custom layer you added, with the layer Id as the key.


function getnearestCustomLocation(){
    var url = "https://cle.api.here.com/2/search/proximity.json";
    
    url= addURLParam(url, "app_id", "YOUR_APP_ID");
    url= addURLParam(url, "app_code", "YOUR_APP_CODE");
    url= addURLParam(url, "proximity", "52.51607,13.37698,4000");
    url= addURLParam(url, "layer_ids", "WAREHOUSES_DIST_3");
    
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() 
    {
        if (this.readyState == 4 && this.status == 200) 
        {
        var myArr = JSON.parse(this.responseText);
        console.log(this.responseText.length);
        for (i=0; i < this.responseText.length; i++)
        {
            newpos= {lat: myArr.geometries[i].nearestLat, lng: myArr.geometries[i].nearestLon};
            var wh_icon = new H.map.Icon("img/warehouse.png");
            wh_marker = new H.map.Marker(newpos,{icon:wh_icon});
            map.addObject(wh_marker);
        }    
        }
    };
    xhttp.open("GET", url, true);
    xhttp.send();
    }

Here I have simply displayed the places in my custom layer 'WAREHOUSES_DIST_3' within 4km of my current location. You can also add them as your routing waypoints. This layer was added using methods discussed in Custom Locations Part-I.

Within a bounding box

Another way of searching for custom locations can be within a given region described by a bounding box. The box within which you would want to search for locations within your custom layer is defined by the latitude and longitude of the upper left, lower and right corners of the box. The result will be all the locations in the given layer Id within the defined box on the map.


https://cle.api.here.com/2/search/bbox.json?app_id=YOUR_APP_ID&app_code=YOUR_APP_CODE&bbox=52.51828,13.33282;52.50535,13.39073&layer_id=WAREHOUSES_DIST_3

Isoline search

Imagine that your truck is on its way for a delivery. There is an emergency and the driver needs to drop the cargo at your nearest warehouse. How would you find this private warehouse en route the pre-fed destination. Isoline lets you find locations that can be reached within a specific distance or within a specific time. This distance or time can be specified in the query as seen in the Isoline Routing example. The way we can use isoline here is by searching for locations in the custom layer, that can be reached within a distance / time of detour along your original destination. How is it different than a normal proximity search with a radius? Well this looks for destinations which will be a certain distance of detour away from your original route. This use-case plays in when you are already en route, while the proximity search is when you are starting out and don't have a specific destination in mind yet. Let's talk about the parameters in this request.


    https://cle.api.here.com/2/search/routeisoline.json?app_id=YOUR_APP_ID&app_code=YOUR_APP_CODE&waypoint0=52.52008,13.41441&waypoint1=52.51574,13.4182&layer_ids=WAREHOUSES_DIST_3&max_detour_distance=1000  

With waypoint0 and waypoint1, we define the start and endpoint of the current route. With the max_detour_distance parameter, we define the detour that we wish to take, in meters from the current route. The result will look something like this:


    {
        "response": {
            "route": [
                {
                    "mode": {
                        "type": "fastest",
                        "transportModes": [
                            "car"
                        ]
                    },
                    "boatFerry": false,
                    "railFerry": false,
                    "waypoint": [
                        {
                            "linkId": "+53501246",
                            "mappedPosition": {
                                "latitude": 52.52008,
                                "longitude": 13.41441
                            },
                            "originalPosition": {
                                "latitude": 52.52008,
                                "longitude": 13.41441
                            },
                            "spot": 0.55626,
                            "seqNrOnRoute": 0
                        },
                        {
                            "linkId": "+733292930",
                            "mappedPosition": {
                                "latitude": 52.51574,
                                "longitude": 13.41824
                            },
                            "originalPosition": {
                                "latitude": 52.51574,
                                "longitude": 13.4182
                            },
                            "spot": 0.25441,
                            "seqNrOnRoute": 1
                        }
                    ],
                    "leg": [
                        {
                            "link": [
                                {
                                    "linkId": "53501246",
                                    "length": 26,
                                    "remainDistance": 775,
                                    "remainTime": 71,
                                    "shape": [
                                        52.51989,
                                        13.41403,
                                        52.52013,
                                        13.41452,
                                        52.52024,
                                        13.4147
                                    ],
                                    "functionalClass": 4
                                },
                                {
                                    "linkId": "779490732",
                                    "length": 15,
                                    "remainDistance": 748,
                                    "remainTime": 71,
                                    "shape": [
                                        52.52024,
                                        13.4147,
                                        52.52035,
                                        13.41483
                                    ],
                                    "functionalClass": 4
                                },
                                {
                                    "linkId": "779490733",
                                    "length": 46,
                                    "remainDistance": 733,
                                    "remainTime": 68,
                                    "shape": [
                                        52.52035,
                                        13.41483,
                                        52.52069,
                                        13.41523
                                    ],
                                    "functionalClass": 4
                                },
                                {
                                    "linkId": "-77272542",
                                    "length": 26,
                                    "remainDistance": 687,
                                    "remainTime": 66,
                                    "shape": [
                                        52.52069,
                                        13.41523,
                                        52.5205,
                                        13.41547
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-77272541",
                                    "length": 39,
                                    "remainDistance": 660,
                                    "remainTime": 61,
                                    "shape": [
                                        52.5205,
                                        13.41547,
                                        52.52022,
                                        13.41583
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-53500310",
                                    "length": 34,
                                    "remainDistance": 620,
                                    "remainTime": 59,
                                    "shape": [
                                        52.52022,
                                        13.41583,
                                        52.52013,
                                        13.41595,
                                        52.51998,
                                        13.41614
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-704317753",
                                    "length": 49,
                                    "remainDistance": 586,
                                    "remainTime": 55,
                                    "shape": [
                                        52.51998,
                                        13.41614,
                                        52.51981,
                                        13.41635,
                                        52.51962,
                                        13.41657
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-704317756",
                                    "length": 29,
                                    "remainDistance": 537,
                                    "remainTime": 52,
                                    "shape": [
                                        52.51962,
                                        13.41657,
                                        52.51956,
                                        13.41664,
                                        52.51951,
                                        13.41669,
                                        52.51939,
                                        13.41679
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-704317755",
                                    "length": 35,
                                    "remainDistance": 507,
                                    "remainTime": 48,
                                    "shape": [
                                        52.51939,
                                        13.41679,
                                        52.51911,
                                        13.41703
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-704285110",
                                    "length": 81,
                                    "remainDistance": 472,
                                    "remainTime": 45,
                                    "shape": [
                                        52.51911,
                                        13.41703,
                                        52.51894,
                                        13.41718,
                                        52.51876,
                                        13.41732,
                                        52.51845,
                                        13.41755
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-704285109",
                                    "length": 53,
                                    "remainDistance": 390,
                                    "remainTime": 42,
                                    "shape": [
                                        52.51845,
                                        13.41755,
                                        52.51822,
                                        13.41769,
                                        52.518,
                                        13.41781
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-77272580",
                                    "length": 56,
                                    "remainDistance": 337,
                                    "remainTime": 35,
                                    "shape": [
                                        52.518,
                                        13.41781,
                                        52.51777,
                                        13.4179,
                                        52.5175,
                                        13.41799
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-1198028424",
                                    "length": 34,
                                    "remainDistance": 280,
                                    "remainTime": 30,
                                    "shape": [
                                        52.5175,
                                        13.41799,
                                        52.51719,
                                        13.41807
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-1198028423",
                                    "length": 49,
                                    "remainDistance": 245,
                                    "remainTime": 25,
                                    "shape": [
                                        52.51719,
                                        13.41807,
                                        52.51701,
                                        13.41811,
                                        52.51675,
                                        13.41815
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-734724633",
                                    "length": 26,
                                    "remainDistance": 196,
                                    "remainTime": 22,
                                    "shape": [
                                        52.51675,
                                        13.41815,
                                        52.51651,
                                        13.41815
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-810879789",
                                    "length": 24,
                                    "remainDistance": 169,
                                    "remainTime": 17,
                                    "shape": [
                                        52.51651,
                                        13.41815,
                                        52.51629,
                                        13.41813
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-810879788",
                                    "length": 68,
                                    "remainDistance": 145,
                                    "remainTime": 15,
                                    "shape": [
                                        52.51629,
                                        13.41813,
                                        52.51602,
                                        13.41812,
                                        52.51585,
                                        13.41811,
                                        52.51568,
                                        13.41806
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-53507141",
                                    "length": 25,
                                    "remainDistance": 77,
                                    "remainTime": 13,
                                    "shape": [
                                        52.51568,
                                        13.41806,
                                        52.5156,
                                        13.41803,
                                        52.51546,
                                        13.41798
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "-53507143",
                                    "length": 14,
                                    "remainDistance": 52,
                                    "remainTime": 6,
                                    "shape": [
                                        52.51546,
                                        13.41798,
                                        52.51541,
                                        13.41818
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "53507142",
                                    "length": 24,
                                    "remainDistance": 37,
                                    "remainTime": 4,
                                    "shape": [
                                        52.51541,
                                        13.41818,
                                        52.51563,
                                        13.41823
                                    ],
                                    "functionalClass": 3
                                },
                                {
                                    "linkId": "733292930",
                                    "length": 12,
                                    "remainDistance": 12,
                                    "remainTime": 3,
                                    "shape": [
                                        52.51563,
                                        13.41823,
                                        52.51606,
                                        13.41825
                                    ],
                                    "functionalClass": 3
                                }
                            ],
                            "length": 775,
                            "travelTime": 71
                        }
                    ],
                    "summary": {
                        "travelTime": 71,
                        "distance": 775,
                        "baseTime": 71,
                        "trafficTime": 71,
                        "flags": []
                    },
                    "searchResult": {
                        "geometries": []
                    }
                }
            ],
            "warnings": []
        },
        "response_code": "200 OK"
    }

Here you see that you can get the link id's of the roads that can be taken to the various locations within the custom layer that can be reached with a detour of 1000 meters.

ERRORS

If you have uploaded the custom layer following the custom location part-I blog, and try to use the isoline search to search places within the layer with a detour, you might get an error which looks like this:


error {
    "issues": [
        {
            "message": "Missing column 'LINK_ID' in layer 'WAREHOUSES_DIST_3'"
        }
    ],
    "error_id": "52e5f3c3-b0fe-4313-9b5a-f60f6f4f610b",
    "response_code": "400 Bad Request"
}   

The issue here is that isoline search can ONLY be used if the uploaded layer of custom locations has a column named LINK_ID. This column contains a parameter associated with the road that connects to the loation. To retreive this LINK_ID, run a batch geocoder with one of the parameters of outcols as 'mapReferenceId' and locationattributes as 'mapReference'. The request should look like this.


    https://batch.geocoder.api.here.com/6.2/jobs?app_id=YOUR_APP_ID&app_code=YOUR_APP_CODE&action=run&header=true&indelim=,&outdelim=,&outcols=latitude,longitude,locationLabel,mapReferenceId&mailto=YOUR_EMAIL_ID&locationattributes=mapReference&outputcombined=true

The body of this post request should contain the locations which you need in your layer.


        recId,searchText,country
        1,"Proskauer Straße 30, Friedrichshain,10247,Berlin",Germany
        2,"Gärtnerstraße 26, Friedrichshain,10245,Berlin",Germany
        3,"Wühlischstraße 17, Friedrichshain,10245,Berlin",Germany

The response is columns 'latitude,longitude,locationLabel,mapReferenceId'. Here the coulumn mapReferenceId will serve as your LINK_ID.

Conclusion

We have created a layer on top of the map with private locations. We have added, updated and deleted locations. We have searched for these locations within a radius, within a box and along an isoline. As much as fleet telematics is a prominent a use-case here, fun applications like maintaining a list of restaurants to visit or museums to visit can also be created using the same set of APIs by getting your credentials at the developer portal. Let me know what you think of the tutorial, try it yourself and feel free to ask questions. Happy coding!