Access map data on-the-fly
In order to access and retrieve map segment data, you can use the SegmentDataLoader. It provides an interface for accessing map data available in the OCM map such as speed limits and road attributes.
NoteThis is a beta release of this feature, so there could be a few bugs and unexpected behaviors. Related APIs may change for new releases without a deprecation process.
- The
SegmentDataLoaderfirst checks if data was installed, prefetched or cached and if not available, it attempts to download the requested tiles online. - The operations are synchronous and will block the thread from which they are called. If called from the main thread, it will block the main thread. For best performance, it is recommended to call these methods from a background thread or to prefetch the map data around your working area.
By calling getSegmentsAroundCoordinates(), you can obtain a list of OCMSegmentId objects representing segments near the specified location. Once retrieved, these IDs can be used to load detailed segment data, including structural and regulatory attributes such as PhysicalAttributes of a road and SegmentSpeedLimit.
For optimal results when working with location-based segment queries, consider using map-matched coordinates rather than raw GPS coordinates. The MapMatcher can align your location signals to the road network, ensuring you retrieve segment data for the correct road position. The MapMatcher already provides some segment information, but if you need the full segment data, you can use the map-matched coordinates with the SegmentDataLoader. See Map matching locations for details on improving location accuracy before querying segment data.
public void loadAndProcessSegmentData() {
List<OCMSegmentId> segmentIds;
SegmentData segmentData;
// The necessary SegmentDataLoaderOptions need to be turned on in order to find the requested information.
// It is recommended to turn on only the data you are interested in by setting the corresponding fields to true.
SegmentDataLoaderOptions segmentDataLoaderOptions = new SegmentDataLoaderOptions();
segmentDataLoaderOptions.loadBaseSpeeds = true;
segmentDataLoaderOptions.loadRoadAttributes = true;
double radiusInMeters = 500;
try {
segmentIds = segmentDataLoader.getSegmentsAroundCoordinates(startGeoCoordinates, radiusInMeters);
for (OCMSegmentId segmentId : segmentIds) {
segmentData = segmentDataLoader.loadData(segmentId, segmentDataLoaderOptions);
List<SegmentSpanData> segmentSpanDataList = segmentData.getSpans();
if (segmentSpanDataList == null) {
Log.e(TAG, "SegmentSpanDataList is null");
continue;
}
for (SegmentSpanData span : segmentSpanDataList) {
Log.d(TAG, "Physical attributes of " + span.toString() + " span.");
Log.d(TAG, "Private roads: " + span.getPhysicalAttributes().isPrivate);
Log.d(TAG, "Dirt roads: " + span.getPhysicalAttributes().isDirtRoad);
Log.d(TAG, "Bridge: " + span.getPhysicalAttributes().isBridge);
Log.d(TAG, "Tollway: " + span.getRoadUsages().isTollway);
Log.d(TAG, "Average expected speed: " + span.getPositiveDirectionBaseSpeedInMetersPerSecond());
}
}
} catch (MapDataLoaderException e) {
throw new RuntimeException(e);
}
}
fun loadAndProcessSegmentData() {
val segmentIds: MutableList<OCMSegmentId>
var segmentData: SegmentData
// The necessary SegmentDataLoaderOptions need to be turned on in order to find the requested information.
// It is recommended to turn on only the data you are interested in by setting the corresponding fields to true.
val segmentDataLoaderOptions = SegmentDataLoaderOptions()
segmentDataLoaderOptions.loadBaseSpeeds = true
segmentDataLoaderOptions.loadRoadAttributes = true
val radiusInMeters = 500.0
if (startGeoCoordinates == null) {
Toast.makeText(context, "You need to add a route beforehand as we use the start coordinates to search for segment data.", Toast.LENGTH_LONG).show()
return
}
Toast.makeText(context, "The app will now load attributes of a map segment. For more details check the logs.", Toast.LENGTH_LONG).show()
val startGeoCoordinatesNonNull = startGeoCoordinates ?: return logError("StartGeoCoordinates is null. Cannot load segment data.")
segmentIds = segmentDataLoader.getSegmentsAroundCoordinates(startGeoCoordinatesNonNull, radiusInMeters)
for (segmentId in segmentIds) {
segmentData = segmentDataLoader.loadData(segmentId, segmentDataLoaderOptions)
val segmentSpanDataList = segmentData.spans
for (span in segmentSpanDataList) {
Log.d(TAG, "Physical attributes of $span span.")
Log.d(TAG, "Private roads: ${span.physicalAttributes?.isPrivate}")
Log.d(TAG, "Dirt roads: ${span.physicalAttributes?.isDirtRoad}")
Log.d(TAG, "Bridge: ${span.physicalAttributes?.isBridge}")
Log.d(TAG, "Tollway: ${span.roadUsages?.isTollway}")
Log.d(TAG, "Average expected speed: ${span.positiveDirectionBaseSpeedInMetersPerSecond}")
}
}
}
You can find an example implementation for this in the "RoutingWithAvoidanceOptions" example app on GitHub.
Updated yesterday