Mobility On-Demand Technical Solution Paper

Filtering By Administrative Area

This document assumes your ride-hailing service includes a backend component that filters drivers based on which administrative area they are in. This level of filtering can be quite imprecise, as it does not take account of traffic conditions or available routes. However, it does reduce the amount of time required to determine ETAs between drivers and passengers and can make the driver selection process more asynchronous to improve passenger experience. Alternatively, you could use administrative areas for other business logic in your system. For example, you could charge different rates based on when the request is made and which area the passenger is in.

A typical workflow for determining which locations are in which administrative area is as follows:
  • Determine the WGS 84 compliant goecoordinates of a location. For instance, the location of various drivers based on the information collected from a special driver app on an Android or iOS mobile device. This assumes your driver app posts the driver's location to the backend at reasonable intervals.
  • Use the HERE Geofencing Extension API to determine which administrative areas contain those locations. Using the results, you could then implement logic in your backend that excludes drivers in particular administrative areas from consideration for rides in other administrative areas.
  • Use the HERE Platform Data Extension API to request maps (known as map tiles) of those areas in order to allow your backend to visualize those areas.
  • Present the current positions of your fleet in your backend. This helps your staff get an understanding of where drivers currently are.
The figure below illustrates the elements in the workflow related to the HERE services.
Figure 1. Service Area Administration Sequence Diagram

To determine the boundary of an administrative area:

  1. Send a request to the Geofencing Extension API with the following query parameters:
    • layer_ids with the values ADMIN_POLY_0,ADMIN_POLY_1,ADMIN_POLY_2,ADMIN_POLY_8,ADMIN_POLY_9
    • proximity with a pair of WGS 84 compliant latitude and longitude components with values between -90 and 90 and -180 and 180 respectively. You can add an optional search radius if you wish. For example, proximity=37.870242,-122.268234, 500 specifies a request for a point in Berkeley, CA with a radius of 500 meters.
    • key_attributes with the value ADMIN_PLACE_ID
The code below illustrates the process described in step 1:

const https = require('https');
const _ = require('lodash');

 * Builds a GET request for the Geofencing Extension using pre-defined adminstrative area layers.
 * This request tests a location for the administrative areas (cities, counties, countries, and others)
 * it is within.
 * location  The location to test for
function buildGfeWithPdeLayersRequestOptions(location) {
  var requestParams = _({
              // The ADMIN_POLY_X layers are layers that contain shapes of administrative areas.  These layers are defined in the Platform Data Extension
              'layer_ids': 'ADMIN_POLY_0,ADMIN_POLY_1,ADMIN_POLY_2,ADMIN_POLY_8,ADMIN_POLY_9',
              // The key_attributes are the attributes for each layer which uniquely identify an entry in this layer.  For the ADMIN_POLY_X layers, these are always ADMIN_PLACE_ID
              'proximity': + ',' + location.lon,
              'app_id': {YOUR_APP_ID},
              'app_code': {YOUR_APP_CODE}
            }).map((value, key) => {
              return key + '=' + encodeURIComponent(value);
  return {
    method: 'GET',
    hostname: '',
    path: ['/1/search/proximity.json', requestParams].join('?')

 * Calls the Geofencing Extension API to find administrative areas a location is within.
 * See buildGfeWithPdeLayersRequestOptions for an explanation of the parameters.
function findAdminAreasForLocation(location) {
  return new Promise((fulfill, reject) => {
    var options = buildGfeWithPdeLayersRequestOptions(location);
    var areas = [];
    var req = https.request(options, (res) => {
      var data = "";
      res.on('data', (d) => {
        data += d;
      res.on('end', () => {
        if(res.statusCode >= 400) {
          reject(new Error(data));
          var json = JSON.parse(data);
          var geometries = json['geometries'];
          if(geometries) {
            areas = geometries.filter((geometry) => {
              return geometry.distance <= 0;
            }).map((geometry) => {
              return {name: geometry.attributes.NAME, admin_layer: geometry.attributes.ADMIN_ORDER, admin_place_id: geometry.attributes.ADMIN_PLACE_ID, geometry: geometry.geometry};
    req.on('error', (err) => {


// Coordinates for downtown Berkeley, CA
var downtownBerkeley = { lat: 37.870242, lon: -122.268234 };

/** Output:
 [  { name: 'United States',
    admin_layer: 'ADMIN_POLY_0',
    admin_place_id: '21000001',
    geometry: 'MULTIPOLYGON(((-0122.34375 37.26563,-0122.34375 37.96875,-0121.64062 37.96875,-0121.64062 
        37.26563,-0122.34375 37.26563)))' },
  { name: 'California',
    admin_layer: 'ADMIN_POLY_1',
    admin_place_id: '21009408',
    geometry: 'MULTIPOLYGON(((-0122.34375 37.26563,-0122.34375 37.96876,-0121.64062 37.96876,-0121.64062 
        37.26564,-0122.34375 37.26563)))' },
  { name: 'Alameda',
    admin_layer: 'ADMIN_POLY_8',
    admin_place_id: '21009409',
    geometry: 'MULTIPOLYGON(((-0122.25586 37.79297,-122.33529 37.79297, ... ,-0122.25586 
        37.79297)))' },
  { name: 'Berkeley',
    admin_layer: 'ADMIN_POLY_9',
    admin_place_id: '21009414',
    geometry: 'MULTIPOLYGON(((-0122.29148 37.88086,-0122.25586 37.88086, ... ,-0122.29148 
        37.88086)))' } ]

Once you have the response containing the information about the administrative areas, you can use that data to help visualize the relevant areas.

To request map tiles to visualize administrative areas:

  1. Send a request to the Platform Data Extension API with the following query parameters:
    • layer=ADMIN_PLACE_n
    • attributes=ADMIN_PLACE_ID
    • values set to the values in the response to the first request

    The result is an array of Layers that contain tiles for these values, along with the appropriate zoom level and tileXY coordinate pairs.

  2. Send a request to the Platform Data Extension API with the following query parameters:
    • layer=ADMIN_POLY_n
    • levels set to values reflecting the zoom levels in the previous response
    • tilexy set to the values reflecting the tileXY values in the previous response

    The response includes all administrative area polygons within those tiles. Filtering for those polygons with the ADMIN_PLACE_IDs values returned in the first step provides you with all geometries for these administrative areas, which you can then use to display the complete administrative area on a map.

For more information, see the API Reference.