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.
The SegmentDataLoader first checks if data was prefetched (cached) and if not available, it attempts to download it from the remote server. 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.
func loadAndProcessSegmentData() {
// The necessary SegmentDataLoaderOptions need to be turned on in order to find the requested information. It is recommended to turn on only the fields that you are interested in.
var segmentDataLoaderOptions = SegmentDataLoaderOptions()
segmentDataLoaderOptions.loadBaseSpeeds = true
segmentDataLoaderOptions.loadRoadAttributes = true
let radiusInMeters = 500.0
guard let startGeoCoordinates = startGeoCoordinates else {
showDialog(title: "SegmentDataLoader", message: "You need to add a route beforehand as we use the start coordinates to load segment data.")
return
}
do {
let segmentIds = try segmentDataLoader?.getSegmentsAroundCoordinates(startGeoCoordinates, radiusInMeters: radiusInMeters)
guard let segmentDataLoader = segmentDataLoader,
let segmentIds = segmentIds else {
print("segmentDataLoader is nil")
return
}
for segmentId in segmentIds {
let segmentData = try segmentDataLoader.loadData(segment: segmentId, options: segmentDataLoaderOptions)
if (segmentData.spans.isEmpty) {
print("SegmentSpanDataList is empty")
continue
}
let segmentSpanDataList = segmentData.spans
for span in segmentSpanDataList {
print("Physical attributes of \(span) span.")
print("Private roads: \(String(describing: span.physicalAttributes?.isPrivate))")
print("Dirt roads: \(String(describing: span.physicalAttributes?.isDirtRoad))")
print("Bridge: \(String(describing: span.physicalAttributes?.isBridge))")
print("Tollway: \(String(describing: span.roadUsages?.isTollway))")
print("Average expected speed: \(String(describing: span.positiveDirectionBaseSpeedInMetersPerSecond))")
}
}
} catch let MapDataLoaderError {
print("Error loading segment data: \(MapDataLoaderError)")
}
}
You can find an example implementation for this in the "RoutingWithAvoidanceOptions" example app on GitHub.
Updated 10 hours ago