For non-commercial use only. It has a limited credit count per minute, a limited set of vehicle profiles and cannot use the flexible mode (ch.disable=true).
For the Geocoding API we have integrated different providers. Each provider has its own prices. To take these differences into account, the prices per geocoding request vary depending on the provider.
The following list shows the credit costs per request for the different providers:
- default: 0.3 credits
 - gisgraphy: 0.3 credits
 - nominatim: 0.9 credits
 - nettoolkit: 0.9 credits
 - opencagedata: 0.9 credits
 
2 months free when billed annually.
Some of the datasets we rely on, like OpenStreetMap, tend to have results in local languages. Some others have results only in English. Specifying a language does not guarantee a response purely in that language. We will, however, do our best to favour that language if our data has it.
            OSM and HERE Maps comparison on https://tools.geofabrik.de/mc/
In template (here `{{ place }}` rendered by Django, not by Vue):
{# Search term dropdown #}
    - 
    
 
            In javascript:
const highlightingEl = { start: '', end: '' };
const autocompletionUrl = 'https://autocomplete.geocoder.api.here.com/6.2/suggest.json';
// Sample of Vue app method
fetchSearchPlaceResults() {
    let vm = this;
    let params = '?' +
        'query=' +  encodeURIComponent(vm.place) +
        '&beginHighlight=' + encodeURIComponent(highlightingEl.start) +
        '&endHighlight=' + encodeURIComponent(highlightingEl.end) +
        '&maxresults=15' +
        '&language=de' + // Show localized
        '&country=DEU,AUT' + // Search only in Germany and Austria
        '&app_id=' + hereAppId +
        '&app_code=' + hereAppCode;
    let request = new XMLHttpRequest();
    request.open('GET', autocompletionUrl + params );
    request.onload = function(e) {
        let data = JSON.parse(request.response);
        if (data.suggestions) {
            vm.searchPlaceResults = data.suggestions;
            vm.showSearchPlaceDropdown(); // Triggers dropdown
        } else {
            vm.hideSearchPlaceDropdown(); // Triggers dropdown
        }
    };
    request.send();
}
        Example of suggestions for Koln.
{
    "suggestions": [
        {
            "label": "Deutschland, Köln, Köln",
            "language": "de",
            "countryCode": "DEU",
            "locationId": "NT_BXqF2OWXjw0Df08cTCVyUB",
            "address": {
                "country": "Deutschland",
                "state": "Nordrhein-Westfalen",
                "county": "Köln",
                "city": "Köln",
                "postalCode": "50667"
            },
            "matchLevel": "city"
        },
        {
            "label": "Deutschland, Köln",
            "language": "de",
            "countryCode": "DEU",
            "locationId": "NT_40ftPMCK.PEJF3psEkvBNA",
            "address": {
                "country": "Deutschland",
                "state": "Nordrhein-Westfalen",
                "county": "Köln"
            },
            "matchLevel": "county"
        }
    ]
}
        Filter results based on the page requirements:
if (data.suggestions) {
    if (document.getElementById('searchbar')) {
        vm.searchPlaceResults = data.suggestions.filter(function (item) {
            return item.matchLevel === 'city';
        });
    }
    else {
        vm.searchPlaceResults = data.suggestions;
    }
    vm.showSearchPlaceDropdown();
}
        In template:
{% block scripts %}
    
{% endblock %}
            In javascript:
let markerIcon = new H.map.Icon(markerImage);
        Now we use SVG to draw a marker.
const pixelRatio = window.devicePixelRatio || 1;
const markerSize = 40 * pixelRatio;
const markerIcon = new H.map.Icon(markerSVGTemplate, {
    size: { w: markerSize, h: markerSize },
    anchor: { x: markerSize / 2, y: markerSize / 2 },
});
        Our custom info window
                
.H_ib * {
    box-sizing: border-box;
}
.H_ib_body {
    box-sizing: border-box;
    width: 320px;
    background: var(--white);
    font-size: 18px;
    color: var(--outer-space);
    margin-right: 35px;
    bottom: 25px;
    box-shadow: 3px 3px 10px 0 rgba(0, 0, 0, 0.5);
}
        Terrain Map Tile
                        Traffic tile
                        Satellite Tile
                        Normal Day Tile
                        Setting map style in javascript
// Map initialization
let platform = new H.service.Platform({
    'app_id': hereAppId,
    'app_code': hereAppCode,
    'useHTTPS': true,
});
let defaultLayers = platform.createDefaultLayers();
let map = new H.Map(
    document.getElementById(mapElementId),
    defaultLayers.normal.map,
    mapOptions,
);
// Setting map style
let mapTileService = platform.getMapTileService({
    type: 'aerial',
});
let mapLayer = mapTileService.createTileLayer(
    'maptile',
    'terrain.day',
    pixelRatio === 1 ? 256 : 512,
    'png8',
    {
        lg: 'GER',
        ppi: pixelRatio === 1 ? undefined : 320,
    },
);
map.setBaseLayer(mapLayer);
                
let strategy = H.clustering.Provider.Strategy.GRID;
// Use FASTGRID strategy only for pages with search results
if (document.getElementById("results")) {
    strategy = H.clustering.Provider.Strategy.FASTGRID;
}
let clusteredDataProvider = new H.clustering.Provider(dataPoints, {
    clusteringOptions: {
        strategy: strategy,
        eps: 30,
        minWeight: 2
    },
});
        For 6000+ points with FASTGRID markers/clusters appear on the initialized map much faster.
GRID
                FASTGRID
                All are closed
                One is open
                Spiderfier source code on GitHub | Screenshots were made based on this demo
For single marker
                For cluster (with arrows to change)
                Cluster SVG template:
const clusterSVGTemplate = ``;
            Preparing cluster icon for rendering:
// Sample of Vue app method
getClusterIcon(clusterWeight) {
    let svgString = clusterSVGTemplate.replace(/{weight}/g, clusterWeight);
    return new H.map.Icon(svgString, {
        size: {w: markerSize, h: markerSize},
        anchor: {x: markerSize / 2, y: markerSize / 2}
    });
},
        import urllib
from django.conf import settings
from django.core.cache import cache
import requests
HERE_GEOCODE_API_URL = 'https://geocode.search.hereapi.com/v1/geocode'
HERE_REVERSE_GEOCODE_API_URL = 'https://revgeocode.search.hereapi.com/v1/revgeocode'
HERE_LOCATION_API_URL = 'https://lookup.search.hereapi.com/v1/lookup'
class HereClient(object):
    def _get_url_params(self, **extra_params):
        params = {'apiKey': settings.HERE_API_KEY, 'lang': settings.HERE_LANGUAGE}
        params.update(**extra_params)
        return urllib.parse.urlencode(params)
    def make_request(self, url, **params):
        url = '%s?%s' % (url, self._get_url_params(**params))
        response = requests.get(url)
        if response.status_code == 200:
            data = response.json()
            return data
    def geocode(self, query):
        data = self.make_request(HERE_GEOCODE_API_URL, q=query)
        if data:
            return data['items']
    def reverse_geocode(self, latitude, longitude):
        params = {'limit': 1, 'at': '%s,%s' % (latitude, longitude)}
        data = self.make_request(HERE_REVERSE_GEOCODE_API_URL, **params)
        if data:
            return data['items']
    def lookup(self, location_id):
        cached_record = cache.get(location_id, None)
        if not cached_record:
            data = self.make_request(HERE_LOCATION_API_URL, id=location_id)
            cache.set(location_id, data)
            return cached_record
        return cached_record
        Model:
from django.contrib.gis.db import models
class Place(models.Model):
    name = models.CharField(max_length=255)
    point = models.PointField()
    def __str__(self):
        return self.name
    @property
    def lat(self):
        return self.point[1]
    @property
    def lng(self):
        return self.point[0]
                API view:
from django.contrib.gis.geos import Point
from rest_framework import generics, serializers
from apps.places.models import Place
class PlaceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Place
        fields = ('name', 'lat', 'lng')
class PlaceListAPIView(generics.ListAPIView):
    queryset = Place.objects.all()
    serializer_class = PlaceSerializer
    def filter_queryset(self, queryset):
        query = self.request.query_params.get('q', None)
        latitude = self.request.query_params.get('lat', None)
        longitude = self.request.query_params.get('lng', None)
        radius = self.request.query_params.get('r', 15) or 15
        if query:
            queryset = queryset.filter(name__search=query)
        if latitude and longitude:
            longitude, latitude = map(float, (longitude, latitude))
            geopoint = Point(longitude, latitude)
            queryset = queryset.filter(
                point__dwithin=(geopoint, radius)
            )
        return queryset
                Haystack search index definition:
from haystack import indexes
from apps.places.models import Place
class PlaceIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, model_attr='name')
    name = indexes.CharField(model_attr='name')
    point = indexes.LocationField(model_attr='point')
    lat = indexes.FloatField(model_attr='lat')
    lng = indexes.FloatField(model_attr='lng')
    def get_model(self):
        return Place
                API view:
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
from haystack.query import SearchQuerySet
from rest_framework import generics, serializers
class SearchRecordSerializer(serializers.Serializer):
    name = serializers.CharField()
    lat = serializers.FloatField()
    lng = serializers.FloatField()
class SearchResultsAPIView(generics.ListAPIView):
    queryset = SearchQuerySet()
    serializer_class = PlaceSerializer
    def filter_queryset(self, queryset):
        query = self.request.query_params.get('q', None)
        latitude = self.request.query_params.get('lat', None)
        longitude = self.request.query_params.get('lng', None)
        radius = self.request.query_params.get('radius', 15) or 15
        if query:
            queryset = queryset.filter(content=query)
        if latitude and longitude:
            longitude, latitude = map(float, (longitude, latitude))
            geopoint = Point(longitude, latitude)
            max_distance = D(km=radius)
            queryset = queryset.dwithin(
                'location', geopoint, max_distance,
            )
        return queryset