High-Level API v2

Note

This is a new experimental module, and it may be changed from one version to the next. At the time of writing, the high-level API v2 does not implement all the features of the former API.

The high-level API v2 of the Location Library provides a way to instantiate various kinds of path matchers and a number of factory methods to help you directly implement your algorithms using the following interfaces:

  • ProximitySearch To find topology segments (vertices) from coordinates.
    ProximitySearches
  • DirectedGraph To navigate the topology with an efficient data structure.
    Graphs
  • PropertyMap To access road, navigation, advanced navigation, and ADAS attributes.
    PropertyMaps

The API also introduces a new cache mechanism which allows re-using blobs that are shared between different catalog versions. This allows a reduction in memory usage compared to the previous approach. The eviction strategy is defined on a catalog basis, allowing the evictions of the layers that are not used anymore.

Setting things up

Before you start using the API, you should add the location-integration-optimized-map-dcl2 dependency:

SBT
Maven
Gradle
libraryDependencies ++= Seq(
  "com.here.platform.location" %% "location-integration-optimized-map-dcl2" % "0.21.788"
)
<dependencies>
    <dependency>
        <groupId>com.here.platform.location</groupId>
        <artifactId>location-integration-optimized-map-dcl2_${scala.compat.version}</artifactId>
        <version>0.21.788</version>
    </dependency>
</dependencies>
dependencies {
    compile group: 'com.here.platform.location', name: 'location-integration-optimized-map-dcl2_2.12', version:'0.21.788'
}

Open a version of Optimized Map for Location Libraries

To start, you need to create an instance of OptimizedMapLayers, which is what the factory of all the algorithms require. You can do this based on a BaseClient instance:

Scala
Java
import com.here.platform.data.client.base.scaladsl.BaseClient
import com.here.platform.location.integration.optimizedmap.OptimizedMapLayers
import com.here.platform.location.integration.optimizedmap.dcl2.OptimizedMapCatalog

val baseClient = BaseClient()
val optimizedMap: OptimizedMapLayers =
  OptimizedMapCatalog.from(optimizedMapHRN).usingBaseClient(baseClient).newInstance.version(42)
import com.here.platform.data.client.base.javadsl.BaseClient;
import com.here.platform.data.client.base.javadsl.BaseClientJava;
import com.here.platform.location.integration.optimizedmap.OptimizedMapLayers;
import com.here.platform.location.integration.optimizedmap.dcl2.javadsl.OptimizedMapCatalog;

BaseClient baseClient = BaseClientJava.instance();
OptimizedMapLayers optimizedMap =
    OptimizedMapCatalog.from(optimizedMapHRN)
        .usingBaseClient(baseClient)
        .newInstance()
        .version(42);

In order to associate places in the real world with vertices in the routing graph, ProximitySearch allows you to search for vertices within a certain distance from a point on the map.

You can create a ProximitySearch instance using its factory class ProximitySearches:

Scala
Java
import com.here.platform.location.core.geospatial._
import com.here.platform.location.inmemory.graph.Vertex
import com.here.platform.location.integration.optimizedmap.geospatial.ProximitySearches

val proximitySearches: ProximitySearches = ProximitySearches(optimizedMap)
val proximitySearch: ProximitySearch[Vertex] = proximitySearches.vertices
val brandenburgerTor: GeoCoordinate = GeoCoordinate(52.516268, 13.377700)
val projections: Iterable[ElementProjection[Vertex]] =
  proximitySearch.search(center = brandenburgerTor, radiusInMeters = 100)
import com.here.platform.location.core.geospatial.ElementProjection;
import com.here.platform.location.core.geospatial.GeoCoordinate;
import com.here.platform.location.core.geospatial.javadsl.ProximitySearch;
import com.here.platform.location.inmemory.graph.Vertex;
import com.here.platform.location.integration.optimizedmap.geospatial.javadsl.ProximitySearches;

ProximitySearches proximitySearches = new ProximitySearches(optimizedMap);
ProximitySearch<GeoCoordinate, Vertex> proximitySearch = proximitySearches.vertices();
GeoCoordinate brandenburgerTor = new GeoCoordinate(52.516268, 13.377700);
Iterable<ElementProjection<Vertex>> projections = proximitySearch.search(brandenburgerTor, 100);

Since the geometries of the vertices are not always rectilinear, in some cases you may want to get one ElementProjection for each segment of the geometry (the segment between consecutive pairs of points).

Note

The following image shows the results from the ProximitySearches.vertices. The search only returns the closest point for each vertex: One result per vertex

By using the ProximitySearches.vertexGeometrySegments variant, you have the option to get more than one projection for each vertex: One result for each geometry segment

Graph

You can navigate the road topology and geometry of the HERE Map Content using a graph abstraction. Each vertex of the graph represents a road (topology segment) in a direction, and each edge a physical connection between roads as explained in the Routing Graph section.

To create a DirectedGraph instance, you can use its factory class Graphs:

Scala
Java
import com.here.platform.location.core.graph.DirectedGraph
import com.here.platform.location.inmemory.graph.{Edge, Vertex}
import com.here.platform.location.integration.optimizedmap.graph.Graphs

val graphs: Graphs = Graphs(optimizedMap)
val graph: DirectedGraph[Vertex, Edge] = graphs.forward
val outEdges: Iterator[Edge] = graph.outEdgeIterator(vertex)
import com.here.platform.location.core.graph.javadsl.DirectedGraph;
import com.here.platform.location.inmemory.graph.Edge;
import com.here.platform.location.inmemory.graph.Vertex;
import com.here.platform.location.integration.optimizedmap.graph.javadsl.Graphs;

Graphs graphs = new Graphs(optimizedMap);
DirectedGraph<Vertex, Edge> graph = graphs.forward();
Iterator<Edge> outEdges = graph.getOutEdgeIterator(vertex);

Note

There are always two vertices associated with a road topology segment, one for each physical direction of travel. PropertyMaps can be used to gather attributes to make decisions, for example PropertyMaps.roadAccess described below can be used to derive information about the direction of travel for various modes of transport.

Path Matcher

To resolve sequences of recorded geographical coordinates to paths on the road topology graph, you can use a path matcher. The path matcher will return information about the position on the road that most likely corresponds to each input point, and the most likely connection (transition) between points.

Path matching
Figure 1. Path matching

Note

Dense and sparse traces of probe data

The sequence of recorded geographical coordinates is called trace or probe trace. The path matchers distinguish between dense and sparse traces. Dense traces are characterized by distances between consecutive probes that are short compared to lengths of the road segments in the map. Typically, probes collected every 1 to 5 seconds are considered dense.

You can create a PathMatcher instance using its factory class PathMatchers:

Scala
Java
import com.here.platform.location.core.geospatial.GeoCoordinate
import com.here.platform.location.core.mapmatching.{MatchedPath, PathMatcher}
import com.here.platform.location.inmemory.graph.Vertex
import com.here.platform.location.integration.optimizedmap.mapmatching.PathMatchers

val pathMatchers = PathMatchers(optimizedMap)
val pathMatcher: PathMatcher[GeoCoordinate, Vertex, Seq[Vertex]] =
  pathMatchers.carPathMatcherWithTransitions
val matchedPath: MatchedPath[Vertex, Seq[Vertex]] = pathMatcher.matchPath(Seq(coordinates))
import com.here.platform.location.core.geospatial.javadsl.GeoCoordinateHolder;
import com.here.platform.location.core.mapmatching.javadsl.MatchedPath;
import com.here.platform.location.core.mapmatching.javadsl.PathMatcher;
import com.here.platform.location.inmemory.graph.Vertex;
import com.here.platform.location.integration.optimizedmap.mapmatching.javadsl.PathMatchers;

PathMatchers pathMatchers = new PathMatchers(optimizedMap);
PathMatcher<GeoCoordinateHolder, Vertex, List<Vertex>> pathMatcher =
    pathMatchers.carPathMatcherWithTransitions();
MatchedPath<Vertex, List<Vertex>> matchedPath =
    pathMatcher.matchPath(Arrays.asList(coordinates));

In order to create path matchers, you can use various methods:

  • The unrestrictedPathMatcherWithoutTransitions creates a map matcher that produces results independent from any driving restriction, and is suitable for dense GPS traces (at least one point every 5 seconds).

    The unrestrictedPathMatcherWithoutTransitions is the most effective method to match to the most probably driven path for dense probes, and all vehicle types. You will not necessarily be able to follow this path by driving, but you can use the results to derive warnings about driving errors.

    The unrestrictedPathMatcherWithoutTransitions may introduce disconnections when consecutive points are not on directly connected topology segments, as it does not use any routing algorithm to compute the transitions.

    The unrestrictedPathMatcherWithTransitions variant will make a bigger effort to reconnect points with a simple shortest path algorithm.

  • The carPathMatcherWithTransitions takes most car driving restrictions into consideration, and is a path matcher specifically configured for cars and sparse data, but will also work on dense data. For example, this path matcher will only match input points to vertices that are accessible by cars according to the roadAccess property.

    The carPathMatcherWithTransitions works better than the unrestrictedPathMatcherWithTransitions for sparse data because it will route between points using a shortest path algorithm that takes into consideration road access and turn restrictions. In some situations, when consecutive points are too far apart (more than about 30 kilometers of on-road distance), they could be considered unreachable and one of them could be matched to Unknown.

    The carPathMatcherWithoutTransition variant is similar but is only suitable for dense data, where the distances between consecutive probes are short compared to vertex lengths in the map.

Note

For more details about the path matcher output, see the API Guide.

  • For advanced scenarios, you can construct an HMMPathMatcher directly, to specify desired path matcher dependencies.

Property Maps

The Location Library provides property maps that allow you to access many map features.

To create a PropertyMap instance, you can use its factory class PropertyMaps and with that you can retrieve, for example, the length of a vertex:

Scala
Java
import com.here.platform.location.core.graph._
import com.here.platform.location.inmemory.graph.Vertex
import com.here.platform.location.integration.optimizedmap.graph.PropertyMaps

val propertyMaps = PropertyMaps(optimizedMap)
val length: PropertyMap[Vertex, Double] = propertyMaps.length
val lengthOfAVertex: Double = length(vertex)
import com.here.platform.location.core.graph.javadsl.PropertyMap;
import com.here.platform.location.inmemory.graph.Vertex;
import com.here.platform.location.integration.optimizedmap.graph.javadsl.PropertyMaps;

PropertyMaps propertyMaps = new PropertyMaps(optimizedMap);
PropertyMap<Vertex, Double> length = propertyMaps.length();
Double lengthOfAVertex = length.get(vertex);

On top of getting the length of a vertex, you can also:

  • Convert between HERE Map Content references and vertices of the Optimized Map for Location Library

  • Retrieve the geometry associated with a vertex

  • Determine whether a position on a vertex is accessible to a particular vehicle type

  • Retrieve the speed with which traffic is usually flowing through the vertex (free-flow speed)

  • Determine whether the turn represented by a given edge is restricted for a particular vehicle type

  • Retrieve road attributes, such as

    Scala
    Java
    import com.here.platform.location.core.graph.RangeBasedProperty
    import com.here.platform.location.integration.optimizedmap.graph.PropertyMaps
    import com.here.platform.location.integration.optimizedmap.roadattributes._
    
    val roadAttributes = PropertyMaps(optimizedMap).roadAttributes
    
    val functionalClasses: Seq[RangeBasedProperty[FunctionalClass]] =
      roadAttributes.functionalClass(vertex)
    
    val overpassUnderpasses: Seq[RangeBasedProperty[OverpassUnderpass]] =
      roadAttributes.overpassUnderpass(vertex)
    
    val officialCountryCodes: Seq[RangeBasedProperty[OfficialCountryCode]] =
      roadAttributes.officialCountryCode(vertex)
    
    val physicalAttributes: Seq[RangeBasedProperty[PhysicalAttribute]] =
      roadAttributes.physicalAttribute(vertex)
    
    val roadClasses: Seq[RangeBasedProperty[RoadClass]] = roadAttributes.roadClass(vertex)
    
    val specialTrafficAreaCategories: Seq[RangeBasedProperty[SpecialTrafficAreaCategory]] =
      roadAttributes.specialTrafficAreaCategory(vertex)
    
    val userDefinedCountryCodes: Seq[RangeBasedProperty[UserDefinedCountryCode]] =
      roadAttributes.userDefinedCountryCode(vertex)
    import com.here.platform.location.core.graph.javadsl.RangeBasedProperty;
    import com.here.platform.location.core.graph.javadsl.RangeBasedPropertyMap;
    import com.here.platform.location.inmemory.graph.Vertex;
    import com.here.platform.location.integration.optimizedmap.graph.javadsl.PropertyMaps;
    import com.here.platform.location.integration.optimizedmap.roadattributes.*;
    
    PropertyMaps.RoadAttributes roadAttributes = new PropertyMaps(optimizedMap).roadAttributes();
    
    RangeBasedPropertyMap<Vertex, FunctionalClass> functionalClass =
        roadAttributes.functionalClass();
    List<RangeBasedProperty<FunctionalClass>> functionalClasses = functionalClass.get(vertex);
    
    RangeBasedPropertyMap<Vertex, OverpassUnderpass> overpassUnderpass =
        roadAttributes.overpassUnderpass();
    List<RangeBasedProperty<OverpassUnderpass>> overpassUnderpasses = overpassUnderpass.get(vertex);
    
    RangeBasedPropertyMap<Vertex, OfficialCountryCode> officialCountryCode =
        roadAttributes.officialCountryCode();
    List<RangeBasedProperty<OfficialCountryCode>> officialCountryCodes =
        officialCountryCode.get(vertex);
    
    RangeBasedPropertyMap<Vertex, PhysicalAttribute> physicalAttribute =
        roadAttributes.physicalAttribute();
    List<RangeBasedProperty<PhysicalAttribute>> physicalAttributes = physicalAttribute.get(vertex);
    
    RangeBasedPropertyMap<Vertex, RoadClass> roadClass = roadAttributes.roadClass();
    List<RangeBasedProperty<RoadClass>> roadClasses = roadClass.get(vertex);
    
    RangeBasedPropertyMap<Vertex, SpecialTrafficAreaCategory> specialTrafficAreaCategory =
        roadAttributes.specialTrafficAreaCategory();
    List<RangeBasedProperty<SpecialTrafficAreaCategory>> specialTrafficAreaCategories =
        specialTrafficAreaCategory.get(vertex);
    List<RangeBasedProperty<UserDefinedCountryCode>> userDefinedCountryCodes =
        roadAttributes.userDefinedCountryCode().get(vertex);
  • Retrieve navigation attributes, such as

    Scala
    Java
    import com.here.platform.location.core.graph.RangeBasedProperty
    import com.here.platform.location.integration.optimizedmap.commonattributes.SpeedLimit
    import com.here.platform.location.integration.optimizedmap.graph.PropertyMaps
    import com.here.platform.location.integration.optimizedmap.navigationattributes._
    
    val navigationAttributes = PropertyMaps(optimizedMap).navigationAttributes
    
    val intersectionInternalCategories: Seq[RangeBasedProperty[IntersectionInternalCategory]] =
      navigationAttributes.intersectionInternalCategory(vertex)
    val laneCategories: Seq[RangeBasedProperty[LaneCategory]] =
      navigationAttributes.laneCategory(vertex)
    val throughLaneCounts: Seq[RangeBasedProperty[Int]] =
      navigationAttributes.throughLaneCount(vertex)
    val physicalLaneCounts: Seq[RangeBasedProperty[Int]] =
      navigationAttributes.physicalLaneCount(vertex)
    val localRoads: Seq[RangeBasedProperty[LocalRoad]] =
      navigationAttributes.localRoad(vertex)
    val roadUsages: Seq[RangeBasedProperty[RoadUsage]] =
      navigationAttributes.roadUsage(vertex)
    val lowMobilities: Seq[RangeBasedProperty[LowMobility]] =
      navigationAttributes.lowMobility(vertex)
    val roadDividers: Seq[RangeBasedProperty[RoadDivider]] =
      navigationAttributes.roadDivider(vertex)
    val speedCategories: Seq[RangeBasedProperty[SpeedCategory]] =
      navigationAttributes.speedCategory(vertex)
    val speedLimit: Seq[RangeBasedProperty[SpeedLimit]] =
      navigationAttributes.speedLimit(vertex)
    val supplementalGeometries: Seq[RangeBasedProperty[SupplementalGeometry]] =
      navigationAttributes.supplementalGeometry(vertex)
    val travelDirection: Seq[RangeBasedProperty[TravelDirection]] =
      navigationAttributes.travelDirection(vertex)
    val urban: Seq[RangeBasedProperty[Boolean]] =
      navigationAttributes.urban(vertex)
    val specialExplication: Option[SpecialExplication] =
      navigationAttributes.specialExplication(edge)
    val throughRoute: Option[ThroughRoute] =
      navigationAttributes.throughRoute(edge)
    val tmcCodes: Seq[RangeBasedProperty[Set[TrafficMessageChannelCode]]] =
      navigationAttributes.trafficMessageChannelCodes(vertex)
    import com.here.platform.location.core.graph.javadsl.PropertyMap;
    import com.here.platform.location.core.graph.javadsl.RangeBasedProperty;
    import com.here.platform.location.core.graph.javadsl.RangeBasedPropertyMap;
    import com.here.platform.location.inmemory.graph.Edge;
    import com.here.platform.location.inmemory.graph.Vertex;
    import com.here.platform.location.integration.optimizedmap.commonattributes.SpeedLimit;
    import com.here.platform.location.integration.optimizedmap.graph.javadsl.PropertyMaps;
    import com.here.platform.location.integration.optimizedmap.navigationattributes.*;
    
    PropertyMaps.NavigationAttributes navigationAttributes =
        new PropertyMaps(optimizedMap).navigationAttributes();
    
    RangeBasedPropertyMap<Vertex, IntersectionInternalCategory> intersectionInternalCategory =
        navigationAttributes.intersectionInternalCategory();
    List<RangeBasedProperty<IntersectionInternalCategory>> intersectionInternalCategories =
        intersectionInternalCategory.get(vertex);
    
    RangeBasedPropertyMap<Vertex, LaneCategory> laneCategory = navigationAttributes.laneCategory();
    List<RangeBasedProperty<LaneCategory>> laneCategories = laneCategory.get(vertex);
    
    RangeBasedPropertyMap<Vertex, RoadUsage> roadUsage = navigationAttributes.roadUsage();
    List<RangeBasedProperty<RoadUsage>> roadUsages = roadUsage.get(vertex);
    
    RangeBasedPropertyMap<Vertex, Integer> throughLaneCount =
        navigationAttributes.throughLaneCount();
    List<RangeBasedProperty<Integer>> throughLaneCounts = throughLaneCount.get(vertex);
    
    RangeBasedPropertyMap<Vertex, Integer> physicalLaneCount =
        navigationAttributes.physicalLaneCount();
    List<RangeBasedProperty<Integer>> physicalLaneCounts = physicalLaneCount.get(vertex);
    
    RangeBasedPropertyMap<Vertex, LocalRoad> localRoad = navigationAttributes.localRoad();
    List<RangeBasedProperty<LocalRoad>> localRoads = localRoad.get(vertex);
    
    RangeBasedPropertyMap<Vertex, LowMobility> lowMobility = navigationAttributes.lowMobility();
    List<RangeBasedProperty<LowMobility>> lowMobilities = lowMobility.get(vertex);
    
    RangeBasedPropertyMap<Vertex, RoadDivider> roadDivider = navigationAttributes.roadDivider();
    List<RangeBasedProperty<RoadDivider>> roadDividers = roadDivider.get(vertex);
    
    RangeBasedPropertyMap<Vertex, SpeedCategory> speedCategory =
        navigationAttributes.speedCategory();
    List<RangeBasedProperty<SpeedCategory>> speedCategories = speedCategory.get(vertex);
    
    RangeBasedPropertyMap<Vertex, SpeedLimit> speedLimit = navigationAttributes.speedLimit();
    List<RangeBasedProperty<SpeedLimit>> speedLimits = speedLimit.get(vertex);
    
    RangeBasedPropertyMap<Vertex, SupplementalGeometry> supplementalGeometry =
        navigationAttributes.supplementalGeometry();
    List<RangeBasedProperty<SupplementalGeometry>> supplementalGeometries =
        supplementalGeometry.get(vertex);
    
    RangeBasedPropertyMap<Vertex, TravelDirection> travelDirection =
        navigationAttributes.travelDirection();
    List<RangeBasedProperty<TravelDirection>> travelDirections = travelDirection.get(vertex);
    
    RangeBasedPropertyMap<Vertex, Boolean> urban = navigationAttributes.urban();
    List<RangeBasedProperty<Boolean>> urbans = urban.get(vertex);
    
    PropertyMap<Edge, Optional<SpecialExplication>> specialExplication =
        navigationAttributes.specialExplication();
    Optional<SpecialExplication> specialExplications = specialExplication.get(edge);
    
    PropertyMap<Edge, Optional<ThroughRoute>> throughRoute = navigationAttributes.throughRoute();
    Optional<ThroughRoute> throughRoutes = throughRoute.get(edge);
    
    RangeBasedPropertyMap<Vertex, Set<TrafficMessageChannelCode>> trafficMessageChannelCodes =
        navigationAttributes.trafficMessageChannelCodes();
    List<RangeBasedProperty<Set<TrafficMessageChannelCode>>> tmcCodes =
        trafficMessageChannelCodes.get(vertex);
  • Retrieve advanced navigation attributes, such as

    Scala
    Java
    import com.here.platform.location.core.graph.{PointBasedProperty, RangeBasedProperty}
    import com.here.platform.location.integration.optimizedmap.advancednavigationattributes._
    import com.here.platform.location.integration.optimizedmap.commonattributes.SpeedLimit
    import com.here.platform.location.integration.optimizedmap.graph.PropertyMaps
    
    val advancedNavigationAttributes =
      PropertyMaps(optimizedMap).advancedNavigationAttributes
    
    val railwayCrossings: Seq[PointBasedProperty[RailwayCrossing]] =
      advancedNavigationAttributes.railwayCrossing(vertex)
    
    val speedLimit: Seq[RangeBasedProperty[SpeedLimit]] =
      advancedNavigationAttributes.speedLimit(vertex)
    
    val gradeCategory: Seq[RangeBasedProperty[GradeCategory]] =
      advancedNavigationAttributes.gradeCategory(vertex)
    
    val scenic: Seq[RangeBasedProperty[Scenic]] =
      advancedNavigationAttributes.scenic(vertex)
    import com.here.platform.location.core.graph.javadsl.PointBasedProperty;
    import com.here.platform.location.core.graph.javadsl.PointBasedPropertyMap;
    import com.here.platform.location.core.graph.javadsl.RangeBasedProperty;
    import com.here.platform.location.core.graph.javadsl.RangeBasedPropertyMap;
    import com.here.platform.location.inmemory.graph.Vertex;
    import com.here.platform.location.integration.optimizedmap.advancednavigationattributes.GradeCategory;
    import com.here.platform.location.integration.optimizedmap.advancednavigationattributes.RailwayCrossing;
    import com.here.platform.location.integration.optimizedmap.advancednavigationattributes.Scenic;
    import com.here.platform.location.integration.optimizedmap.commonattributes.SpeedLimit;
    import com.here.platform.location.integration.optimizedmap.graph.javadsl.PropertyMaps;
    
    PropertyMaps.AdvancedNavigationAttributes advancedNavigationAttributes =
        new PropertyMaps(optimizedMap).advancedNavigationAttributes();
    
    PointBasedPropertyMap<Vertex, RailwayCrossing> railwayCrossing =
        advancedNavigationAttributes.railwayCrossing();
    List<PointBasedProperty<RailwayCrossing>> railwayCrossings = railwayCrossing.get(vertex);
    
    RangeBasedPropertyMap<Vertex, SpeedLimit> speedLimit =
        advancedNavigationAttributes.speedLimit();
    List<RangeBasedProperty<SpeedLimit>> speedLimits = speedLimit.get(vertex);
    
    RangeBasedPropertyMap<Vertex, GradeCategory> gradeCategory =
        advancedNavigationAttributes.gradeCategory();
    List<RangeBasedProperty<GradeCategory>> gradeCategories = gradeCategory.get(vertex);
    
    RangeBasedPropertyMap<Vertex, Scenic> scenic = advancedNavigationAttributes.scenic();
    List<RangeBasedProperty<Scenic>> scenics = scenic.get(vertex);
  • Retrieve ADAS attributes, such as

    Scala
    Java
    import com.here.platform.location.core.graph.{PointBasedProperty, RangeBasedProperty}
    import com.here.platform.location.integration.optimizedmap.adasattributes._
    import com.here.platform.location.integration.optimizedmap.graph.PropertyMaps
    
    val adasAttributes = PropertyMaps(optimizedMap).adasAttributes
    
    val builtUpAreaRoad: Seq[RangeBasedProperty[BuiltUpAreaRoad]] =
      adasAttributes.builtUpAreaRoad(vertex)
    
    val linkAccuracy: Seq[RangeBasedProperty[Int]] = adasAttributes.linkAccuracy(vertex)
    
    val slope: Seq[PointBasedProperty[Slope]] = adasAttributes.slope(vertex)
    
    val curvatureHeading: Seq[PointBasedProperty[CurvatureHeading]] =
      adasAttributes.curvatureHeading(vertex)
    
    val edgeCurvatureHeading: Option[CurvatureHeading] =
      adasAttributes.edgeCurvatureHeading(edge)
    
    val elevation: Seq[PointBasedProperty[Elevation]] =
      adasAttributes.elevation(vertex)
    import com.here.platform.location.core.graph.javadsl.*;
    import com.here.platform.location.inmemory.graph.Edge;
    import com.here.platform.location.inmemory.graph.Vertex;
    import com.here.platform.location.integration.optimizedmap.adasattributes.BuiltUpAreaRoad;
    import com.here.platform.location.integration.optimizedmap.adasattributes.CurvatureHeading;
    import com.here.platform.location.integration.optimizedmap.adasattributes.Elevation;
    import com.here.platform.location.integration.optimizedmap.adasattributes.Slope;
    import com.here.platform.location.integration.optimizedmap.graph.javadsl.PropertyMaps;
    
    PropertyMaps.AdasAttributes adasAttributes = new PropertyMaps(optimizedMap).adasAttributes();
    
    RangeBasedPropertyMap<Vertex, BuiltUpAreaRoad> builtUpAreaRoad =
        adasAttributes.builtUpAreaRoad();
    List<RangeBasedProperty<BuiltUpAreaRoad>> builtUpAreaRoads = builtUpAreaRoad.get(vertex);
    
    RangeBasedPropertyMap<Vertex, Integer> linkAccuracy = adasAttributes.linkAccuracy();
    List<RangeBasedProperty<Integer>> linkAccuracies = linkAccuracy.get(vertex);
    
    PointBasedPropertyMap<Vertex, Slope> slope = adasAttributes.slope();
    List<PointBasedProperty<Slope>> slopes = slope.get(vertex);
    
    PointBasedPropertyMap<Vertex, CurvatureHeading> curvatureHeading =
        adasAttributes.curvatureHeading();
    List<PointBasedProperty<CurvatureHeading>> curvatureHeadings = curvatureHeading.get(vertex);
    
    PropertyMap<Edge, Optional<CurvatureHeading>> edgeCurvatureHeading =
        adasAttributes.edgeCurvatureHeading();
    Optional<CurvatureHeading> edgeCurvatureHeadings = edgeCurvatureHeading.get(edge);
    
    PointBasedPropertyMap<Vertex, Elevation> elevation = adasAttributes.elevation();
    List<PointBasedProperty<Elevation>> elevations = elevation.get(vertex);

Basic cache configuration and cache statistics

OptimizedMapCatalog allows to set the amount of bytes to be used by the blob cache and the number of entries to be used by the metadata cache. When the number of metadata cache entries is not specified, a reasonable default based on blob cache size is used.

Once your cache is loaded with data, it can be inspected to know few important statistics:

Scala
Java
import com.here.platform.data.client.base.scaladsl.BaseClient
import com.here.platform.data.client.v2.api.scaladsl.versioned.CachingVersionedLayers
import com.here.platform.location.integration.optimizedmap.dcl2.OptimizedMapCatalog

val baseClient: BaseClient = BaseClient()
val optimizedMap: OptimizedMapCatalog =
  OptimizedMapCatalog
    .from(optimizedMapHRN)
    .usingBaseClient(baseClient)
    .withMaxBlobCacheSizeBytes(100L * 1024 * 1024)
    .withMaxMetadataCacheEntryCount(10000L)
    .newInstance
val versionedLayers: CachingVersionedLayers = optimizedMap.versionedLayers
println(versionedLayers.blobCacheStats)
println(versionedLayers.metadataCacheStats)
import com.here.platform.data.client.base.javadsl.BaseClient;
import com.here.platform.data.client.base.javadsl.BaseClientJava;
import com.here.platform.data.client.v2.api.javadsl.versioned.CachingVersionedLayers;
import com.here.platform.location.integration.optimizedmap.dcl2.javadsl.OptimizedMapCatalog;

BaseClient baseClient = BaseClientJava.instance();
OptimizedMapCatalog optimizedMap =
    OptimizedMapCatalog.from(optimizedMapHRN)
        .usingBaseClient(baseClient)
        .withMaxBlobCacheSizeBytes(100 * 1024 * 1024)
        .withMaxMetadataCacheEntryCount(10000)
        .newInstance();
CachingVersionedLayers versionedLayers = optimizedMap.versionedLayers();
System.out.println(versionedLayers.getBlobCacheStats());
System.out.println(versionedLayers.getMetadataCacheStats());

Re-use an externally created cache

There are cases when you need to re-use an externally created cache for various reasons, for example if you want to pass a pre-filled cache to OptimizedMapLayers:

Scala
Java
import com.here.platform.data.client.base.scaladsl.BaseClient
import com.here.platform.data.client.v2.api.scaladsl.versioned.CachingVersionedLayers
import com.here.platform.data.client.v2.caching.caffeine.scaladsl._
import com.here.platform.location.integration.optimizedmap.OptimizedMapLayers
import com.here.platform.location.integration.optimizedmap.dcl2.{
  OptimizedMapCatalog,
  OptimizedMapVersionedLayers
}

val baseClient = BaseClient()
val versionedLayerReadersConfiguration = OptimizedMapCatalog.versionedLayerReadersConfiguration(
  maxBlobCacheSizeBytes = 100 * 1024 * 1024,
  maxMetadataCacheEntryCount = Some(10000))

val blobCache = BlobCacheBuilder(versionedLayerReadersConfiguration).build
val metadataCache = MetadataCacheBuilder(versionedLayerReadersConfiguration).build

val optimizedMapCatalog = OptimizedMapCatalog
  .from(optimizedMapHRN)
  .usingBaseClient(baseClient)
  .withVersionedLayerReadersCache(blobCache, metadataCache)
  .newInstance

val optimizedMap: OptimizedMapLayers =
  new OptimizedMapVersionedLayers(optimizedMapCatalog.versionedLayers, 42)

val versionedLayers: CachingVersionedLayers = optimizedMapCatalog.versionedLayers
println(versionedLayers.blobCacheStats)
println(versionedLayers.metadataCacheStats)
import com.github.benmanes.caffeine.cache.Cache;
import com.here.platform.data.client.base.javadsl.BaseClient;
import com.here.platform.data.client.base.javadsl.BaseClientJava;
import com.here.platform.data.client.v2.api.javadsl.versioned.CachingVersionedLayers;
import com.here.platform.data.client.v2.caching.caffeine.javadsl.BlobCacheBuilder;
import com.here.platform.data.client.v2.caching.caffeine.javadsl.MetadataCacheBuilder;
import com.here.platform.data.client.v2.caching.javadsl.versioned.VersionedLayerReadersConfiguration;
import com.here.platform.data.client.v2.caching.model.versioned.LayerMetadata;
import com.here.platform.data.client.v2.caching.model.versioned.LayerMetadataKey;
import com.here.platform.data.client.v2.caching.model.versioned.OptionalLayerMetadata;
import com.here.platform.location.integration.optimizedmap.OptimizedMapLayers;
import com.here.platform.location.integration.optimizedmap.dcl2.javadsl.OptimizedMapCatalog;

BaseClient baseClient = BaseClientJava.instance();

VersionedLayerReadersConfiguration versionedLayerReadersConfiguration =
    OptimizedMapCatalog.newVersionedLayerReadersConfigurationBuilder()
        .withMaxBlobCacheSizeBytes(100 * 1024 * 1024)
        .withMaxMetadataCacheEntryCount(10000)
        .build();

Cache<LayerMetadata, Object> blobCache =
    new BlobCacheBuilder(versionedLayerReadersConfiguration).build();
Cache<LayerMetadataKey, OptionalLayerMetadata> metadataCache =
    new MetadataCacheBuilder(versionedLayerReadersConfiguration).build();

OptimizedMapCatalog optimizedMapCatalog =
    OptimizedMapCatalog.from(optimizedMapHRN)
        .usingBaseClient(baseClient)
        .withVersionedLayerReadersCache(blobCache, metadataCache)
        .newInstance();

OptimizedMapLayers optimizedMap = optimizedMapCatalog.version(42);

CachingVersionedLayers versionedLayers = optimizedMapCatalog.versionedLayers();
System.out.println(versionedLayers.getBlobCacheStats());
System.out.println(versionedLayers.getMetadataCacheStats());

results matching ""

    No results matching ""