How to Retrieve Administrative Place Hierarchies (Country, State, County, City, and District) Using the HERE Map Attributes API

Symptoms

Customers may need to:

Retrieve a list of countries and administrative areas from HERE map data.
Find all states, counties, cities, or districts for a specific country.
Determine which cities belong to a particular state or region.
Locate all tile IDs associated with an administrative place.
Traverse the administrative hierarchy from Country → State → County → City → District.
Understand which ADMIN_PLACE layer corresponds to a specific administrative level.

Answer
------

The HERE Map Attributes API stores administrative places in different layers based on their hierarchy level. To retrieve administrative places such as states, counties, cities, or districts, first identify the parent administrative place, obtain its tile coverage using the Map Index API, convert the tile IDs to the target layer level, and then query the appropriate ADMIN_PLACE layer.

This article provides examples for:

* Getting all countries
* Getting tile IDs for an administrative place
* Retrieving all cities within a country

Applicable Products
-------------------

* HERE Map Attributes API v8

List of all map layers

| | | | |
| --- | --- | --- | --- |
| Administrative order. | Area name in most countries | Layer | Level |
| 0 = Country type 1111 | country | ADMIN_PLACE_0 link | 7 |
| 1 = Order1 type 1112 | state | ADMIN_PLACE_1 link | 8 |
| 2 = Order2 type 1113 | county | ADMIN_PLACE_2 link | 9 |
| 8 = Order8 type 1119 | city | ADMIN_PLACE_8 link | 10 |
| 9 = Built-up type 3110 | district | ADMIN_PLACE_9 link | 11 |

Example 1: Get a List of Countries

1. Request: https://smap.hereapi.com/v8/maps/attributes?in=tile:0&layers=COUNTRY&apikey=yourapikey

2. From response you can search your interested country by ISO_COUNTRY_CODE

3. Remember the COUNTRY_ID. This is ADMIN_PLACE_ID in layer property. For example country Slovakia: 20428682

Example 2: Get All tileIds for a Country
----------------------------------------

1. Request: https://smap.hereapi.com/v8/maps/index?apikey=yourapikey&layer=ADMIN_PLACE_0&attributes=ADMIN_PLACE_ID&values=20428682

2. In response we get "tileIDs": [25232,25228,25485,24973,25230,25487,25484,25227,25229,25486,24972,25231]

Example 3: Calculate tileIds count for all city administrative places in a specific country
-------------------------------------------------------------------------------------------

1. We will use Slovakia as an example. From above table we know that for city administrative place is the level is 10 and layer is ADMIN_PLACE_8

2. Below is the code needed to calculate the count

<br />proc getCoord*(level, tileX, tileY: int): (float, float) = let tileSize = 180 / (2 ^ level) (tileY.float * tileSize - 90, tileX.float * tileSize - 180) #return coorinates as tuple (float, float)proc getTileXY*(level: int, lat, lng: float): (int, int) = let tileSize = 180 / (2 ^ level) (trunc( (lng + 180) / tileSize ).int, trunc( (lat + 90) / tileSize ).int)#convert TileId(TileXY) to another levelproc toTileXYOtherLevel*(fromLevel, fromTileX, fromTileY, toLevel: int): seq[(int, int)] = let c = getCoord(fromLevel, fromTileX, fromTileY) let tileXY = getTileXY(toLevel, c[0], c[1]) if fromLevel < toLevel: let cntLevels = (toLevel - fromLevel) * 2 - 1 for x in 0..cntLevels: for y in 0..cntLevels: result.add (tileXY[0] + x, tileXY[1] + y) else: result.add tileXYproc toTileId(tileXy: (int, int), level: int): int = tileXy[1] * 2 * (2 ^ level) + tileXy[0]proc toTileIds(tileXys: seq[(int, int)], level: int): seq[int] = for tileXy in tileXys: result.add toTileId(tileXy, level)#[getTileXYLevel calculates tileX and tileY out of a given tileId and a level @param tileId - the tile id @param level - the PDE layer level]#proc getTileXYLevel(tileId: int, level: int): (int, int, int) = let numTilesVertical = 1 shl level #left shift, equivalent to JAVA: 1L << level let tileX = tileId mod (2 * numTilesVertical) if (tileX < 0 or tileX >= numTilesVertical * 2): echo ("Invalid tileX=" & $tileX & " for level " & $level & ", must be [0 ... " & $(numTilesVertical * 2 - 1) & "]") let tileY = ((tileId - tileX) / (2 * numTilesVertical)).int if (tileY < 0 or tileY >= numTilesVertical): echo("Invalid tileY=" & $tileY & " for level " & $level & ", must be [0 ... " & $(numTilesVertical - 1) & "]"); (tileX, tileY, level)proc tileIdsToOtherLevel(fromTileIds: seq[int], fromLevel: int, toLevel: int): seq[int] = var tileXysFromLevel = newSeq[(int, int, int)]() #all TileXys for fromTileIds (tuple[tileX, tileY, level]) for tileId in fromTileIds: let tileXy = getTileXYLevel(tileId, fromLevel) #decode tileId to tileX & tileY tileXysFromLevel.add tileXy var allTileXysToLevel = newSeq[seq[(int, int)]]() #all TileXys for all toLevel in fromLevel for tileXy in tileXysFromLevel: let tileXysToLevel = toTileXYOtherLevel(fromLevel, tileXy[0], tileXy[1], toLevel) #convert the tileX & tileY to another level: in result is sequence of tileX & tileY allTileXysToLevel.add tileXysToLevel for tileXys in allTileXysToLevel: result.add toTileIds(tileXys, toLevel) #convert the sequence of tileX & tileY to sequense of tileIds<br />

3. Above code is only functionality, below code is main code which uses above code:

<br />let tileIdsCountry = @[ 25232, 25228, 25485, 24973, 25230, 25487, 25484, 25227, 25229, 25486, 24972, 25231 ] #This we got from chapter III. ISO_COUNTRY_CODE: SVK - Slovakia#10 is level for City level (or Admin Order8)let tileIdsCities = tileIdsToOtherLevel(tileIdsCountry, 7, 10)echo "tileIdsCities count:", tileIdsCities.lenecho tileIdsCities<br />

4. The result is:

tileIdsCities count:432

@[1606784, 1608832, 1610880, 1612928, 1614976, 1617024, 1606785, 1608833, 1610881, 1612929, 1614977, 1617025, 1606786, 1608834, 1610882, 1612930, 1614978, 1617026, 1606787, 1608835, 1610883, 1612931, 1614979, 1617027, 1606788, 1608836, 1610884, 1612932, 1614980, 1617028, 1606789, 1608837, 1610885, 1612933, 1614981, 1617029, 1606752, 1608800, 1610848, 1612896, 1614944, 1616992, etc...

Example 4: Retrieve all cities in a country
-------------------------------------------

1. Use the tileIds retrieved in example 3.

2. Request should look like: https://smap.hereapi.com/v8/maps/attributes?layers=ADMIN_PLACE_8,ADMIN_PLACE_8,ADMIN_PLACE_8,ADMIN_PLACE_8,ADMIN_PLACE_8∈=tile:1524840,1526888,1528936,1530984,1533032&apikey=yourapikey

2. The example API call only used five tileIds but you can request up to 64 tileIDs. Because of this 64 titleIds maximum limit, you need to send multiple requests. So for 432 tileIds you would need 7 separate requests.

3. In results filter out all rows with "COUNTRY_ID" != "20428682"

Keywords
--------

HERE Map Attributes API, Map Index API, administrative hierarchy, COUNTRY_ID, ADMIN_PLACE_ID, ADMIN_PLACE_0, ADMIN_PLACE_1, ADMIN_PLACE_2, ADMIN_PLACE_8, ADMIN_PLACE_9, country tiles, state tiles, city lookup, district lookup, tile conversion


Did this page help you?