Build a Node.js and HERE Maps JS application to search, visualize, and filter HERE On-Street and Off-Street Parking results, including drawable curbside parking segments from On-Street segmentAnchor
Visualizing HERE On-Street and Off-Street Parking APIs with HERE Maps API for JavaScript
========================================================================================
Overview
--------
Customers often need to help drivers find suitable parking near a destination, understand whether a facility has availability, and check if curbside parking is actually usable based on local restrictions.
This KB explains how to build a Node.js application using HERE Maps API for JavaScript together with HERE On-Street Parking API and HERE Off-Street Parking API.
The attached sample project demonstrates how to:
Search a place using HERE Autosuggest.
Search nearby off-street parking facilities.
Search on-street curbside parking within a map area.
Draw on-street parking segments on the map using segmentAnchor references.
Show parking details in a clean map popup.
Filter on-street results by restriction type, such as residents-only, disabled parking, commercial/loading, and strict no-parking rules.
> Note: HERE On-Street Parking API availability depends on customer entitlement and is intended for automotive OEM in-vehicle use cases.
---
Use case
--------
A driver searches for a destination, for example a street, building, POI, or neighborhood. The application then shows nearby parking options:
1. Off-street parking
Parking facilities such as garages, car parks, or managed parking locations.
2. On-street parking
Curbside parking segments along the road, including availability probability, capacity, side of road, payment options, and restrictions.
The user can click a result from the list or directly on the map to view the relevant parking details.
---
APIs used
---------
The sample application uses the following HERE services:
### HERE Maps API for JavaScript
Used to render the interactive map, markers, polylines, and map popups.<br /><br />
### HERE Autosuggest API
Used to search for places and move the map to the selected result.<br />https://autosuggest.search.hereapi.com/v1/autosuggest<br />
### HERE Off-Street Parking API
Used to search parking facilities near a point.<br />https://parking-v2.cc.api.here.com/parking/facilities.json<br />
Example:<br />curl "https://parking-v2.cc.api.here.com/parking/facilities.json?prox=52.51638,13.38244,500" \ <br /> -H "Authorization: Bearer "<br />
### HERE On-Street Parking API
Used to search curbside parking segments inside a bounding box.<br />https://osp.cc.api.here.com/parking/segments<br />
Example:<br />curl "https://osp.cc.api.here.com/parking/segments?bbox=52.5200,13.3800,52.5120,13.3900&geometryType=tpegOpenLR&geometryType=segmentAnchor" \ <br /> -H "Authorization: Bearer "<br />
### HERE Map Attributes API
Used to resolve On-Street Parking segmentAnchor references into drawable road geometry.<br />https://smap.hereapi.com/v8/maps/attributes/segments<br />
Example:<br />curl "https://smap.hereapi.com/v8/maps/attributes/segments?segmentRefs=here:cm:segment:81650110%23%2B0..1&attributes=ROAD_GEOM_FCn(LAT,LON)" \ <br /> -H "Authorization: Bearer "<br />
---
High-level architecture
-----------------------
The sample project uses a simple browser and Node.js architecture.<br />Browser <br /> | <br /> | HERE Maps JS rendering <br /> | Search UI, filters, map popup <br /> | <br />Node.js backend <br /> | <br /> | Creates HERE OAuth bearer token <br /> | Calls Parking APIs securely <br /> | Calls Map Attributes API securely <br /> | <br />HERE APIs<br />
The HERE access key secret must stay on the backend. The browser should never expose OAuth credentials.
---
Project structure
-----------------
The attached Node.js project follows this structure:<br />here-parking-js-app/ <br /> package.json <br /> .env <br /> src/ <br /> server.js <br /> oauth.js <br /> hereClient.js <br /> geo.js <br /> normalizers.js <br /> segmentAnchorResolver.js <br /> public/ <br /> index.html <br /> app.js <br /> styles.css <br /> README.md<br />
---
Running the sample project
--------------------------
After downloading and extracting the attached project:<br />cd here-parking-js-app <br />npm install <br />npm start<br />
Open:<br />http://localhost:3000<br />
The .env file should contain the HERE API key and HERE OAuth credentials.<br />HERE_API_KEY= <br />HERE_ACCESS_KEY_ID= <br />HERE_ACCESS_KEY_SECRET= <br />PORT=3000<br />
---
Application flow
----------------
### 1. Search for a place
The user starts by searching for a destination using HERE Autosuggest.
When a place is selected:
the map moves to that location,
a search marker is placed on the map,
latitude and longitude fields are updated,
parking search can be started from that location.
### 2. Search off-street parking
For off-street parking, the app calls:<br />/parking/facilities.json?prox=,,<br />
Each result can include:
facility name,
address,
distance,
opening status,
total spaces,
availability,
payment methods,
height restriction,
pricing,
contact details.
The app renders off-street results as markers on the map.
### 3. Search on-street parking
For on-street parking, the app creates a small bounding box around the selected point.
The On-Street Parking API has a bounding box size limit, so the app keeps the requested search area within the supported range.
The request includes:<br />geometryType=tpegOpenLR <br />geometryType=segmentAnchor<br />
The key field for drawing the curbside segment is segmentAnchor.
Example response fragment:<br />{ <br /> "segmentAnchor": { <br /> "orientedSegmentRef": [ <br /> { <br /> "segmentRef": { <br /> "identifier": "here:cm:segment:81650110" <br /> }, <br /> "inverted": true <br /> } <br /> ], <br /> "attributeOrientation": "FORWARD" <br /> } <br />}<br />
The application should not use the Parking API parking segment ID for road drawing. That ID identifies the parking record. To draw the road geometry, use the segmentAnchor.orientedSegmentRef[].segmentRef.identifier.
---
Drawing on-street parking segments
----------------------------------
The On-Street Parking API gives a topology segment reference, not direct latitude and longitude points.
To draw the curb segment:
1. Read the segmentAnchor references.
2. Extract each here:cm:segment: value.
3. Call Map Attributes API with ROAD_GEOM_FCn(LAT,LON).
4. Decode the returned compressed delta geometry.
5. Draw the decoded geometry as a HERE Maps JS polyline.
6. Apply the inverted direction when needed.
7. Highlight the selected curb line when the user clicks a result.
Example segment reference:<br />here:cm:segment:81650110<br />
Map Attributes request:<br />/v8/maps/attributes/segments <br /> ?segmentRefs=here:cm:segment:81650110%23%2B0..1 <br /> &attributes=ROAD_GEOM_FCn(LAT,LON)<br />
Geometry decoding logic:<br />function decodeRoadGeometry(latString, lonString) { <br /> const latDeltas = String(latString).split(",").map(Number); <br /> const lonDeltas = String(lonString).split(",").map(Number); <br /> <br /> let currentLat = 0; <br /> let currentLon = 0; <br /> const points = []; <br /> <br /> for (let i = 0; i < latDeltas.length; i++) { <br /> currentLat += latDeltas[i]; <br /> currentLon += lonDeltas[i]; <br /> <br /> points.push({ <br /> lat: currentLat / 100000, <br /> lng: currentLon / 100000 <br /> }); <br /> } <br /> <br /> return points; <br />}<br />
Drawing the polyline:<br />function drawParkingSegment(points, style) { <br /> const lineString = new H.geo.LineString(); <br /> <br /> points.forEach(point => { <br /> lineString.pushPoint({ <br /> lat: point.lat, <br /> lng: point.lng <br /> }); <br /> }); <br /> <br /> return new H.map.Polyline(lineString, { <br /> style: { <br /> lineWidth: style.lineWidth || 6, <br /> strokeColor: style.strokeColor || "rgba(255, 190, 40, 0.95)" <br /> } <br /> }); <br />}<br />
---
On-street duplicate handling
----------------------------
On-street parking results can contain multiple parking records for the same physical curb segment. This can happen when different rules, capacities, or restrictions are associated with the same road geometry.
The sample application merges duplicate map-rendered segments so the same curb is not drawn many times.
The UI still keeps the meaningful parking information, but only one curb line is rendered for the same physical segment.
---
On-street restriction filters
-----------------------------
On-street results are grouped into customer-friendly tabs.
Recommended tabs:
### Good first
Shows the most useful parking results first based on availability, probability, capacity, and rule usability.
This tab should avoid clearly restricted results such as:
strict no parking,
residents-only,
disabled parking-only, unless the user specifically needs disabled parking.
### No restrictions
Shows parking records without meaningful restrictions.
### Commercial/loading
Shows rules such as:
Loading only
Commercial vehicles only
Loading or commercial vehicles only
Example raw rule:<br />NO_PARKING except LOADING_ONLY, COMMERCIAL_ONLY<br />
Customer-facing label:<br />Loading or commercial vehicles only<br />
### Residents only
Shows parking where the rule is restricted to residents.
Example raw rule:<br />NO_PARKING except RESIDENTS_ONLY<br />
Customer-facing label:<br />Residents only<br />
### Strict no parking
Shows only pure no-parking results.
Example raw rule:<br />NO_PARKING<br />
Customer-facing label:<br />No parking<br />
### Disabled parking
Shows disabled parking results, including mixed cases.
Examples:<br />NO_PARKING except DISABLED_ONLY<br />
or records where allowed vehicle type is:<br />DISABLED<br />
Customer-facing label:<br />Disabled parking only<br />
Important edge case:
If a segment contains disabled-related rules together with loading or commercial rules, it should still appear in the Disabled parking tab. This helps users looking specifically for disabled parking find all potentially relevant results.
### All
Shows all returned on-street records.
---
Customer-facing popup behavior
------------------------------
The sample app avoids showing technical implementation details to the end user.
When a user clicks a drawer result, curb line, or facility marker:
the selected result is highlighted,
the map zooms to that result,
the previous popup closes automatically,
a new popup opens with customer-relevant information only.
For on-street parking, the popup shows:
address or street name,
capacity,
available spots if available,
probability,
trend,
side of road,
allowed vehicle type,
payment methods,
prices,
parking rules,
last updated time.
For off-street parking, the popup shows:
facility name,
address,
distance,
open status,
total spaces,
availability,
height restriction,
payment methods,
prices,
contact details.
Avoid showing backend or geometry details such as:
segmentAnchor,ROAD_GEOM_FCn,
Map Attributes layer names,
OAuth flow details,
merged internal parking IDs,
geometry source,
geometry point count.
These are useful for debugging, but they are not helpful for the end user.
---
Recommended user instructions in the UI
---------------------------------------
Use clear instructions instead of technical architecture text.
Example:<br />Search for a place, then choose On-street, Off-street, or Both. <br /> <br />On-street results show curbside parking along the road. Use the rule filters to quickly find general parking, residents-only parking, disabled parking, commercial/loading zones, or no-parking areas. <br /> <br />Click a card, curb line, or parking marker to see details. The selected parking option will be highlighted on the map.<br />
---
Notes and limitations
---------------------
Parking API coverage and returned attributes vary by city and data availability.
Dynamic availability is not guaranteed for every parking record.
On-Street Parking API requires the correct customer entitlement.
segmentAnchor is the preferred way to draw on-street curb geometry.
For production, keep HERE OAuth credentials only on the server side.
---
Summary
-------
The attached Node.js project demonstrates a complete parking visualization workflow using HERE APIs.
It provides a clean user experience where customers can:
search for a destination,
view nearby parking options,
distinguish off-street and on-street parking,
see curbside segments directly on the map,
filter on-street parking by rule type,
* click any result to view readable parking details.
This approach is suitable as a reference implementation for parking discovery, automotive navigation, city mobility, and in-vehicle parking assistance use cases.
Updated 3 days ago