Geocoder
This module provides online geocoding functionalities (searching for addresses by text with optional filters) using the BeMap API (data provider is HERE). It also provides offline reversed geocoding functionalities (converting location to an address) using local map data.
Dependencies
This module depends on other BeNomad's modules :
Error Manager
Core
BeMapAPI
Vehicle Manager
Other module's dependencies :
implementation "com.google.code.gson:gson:2.8.7"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.10"
implementation "androidx.core:core-ktx:1.9.0"
implementation "androidx.appcompat:appcompat:1.3.0"
implementation "com.google.android.material:material:1.8.0"Geocoder
In order to interact with the geocoding online service, you need to create an OnlineGeocoder Instance. The authorization data needed to interact with this API will be automatically fetched from the license file. (See the Core documentation for more info about the licensing process)
val geocoder = OnlineGeoCoder(applicationContext)Querying for suggestions with given text can be made with the call to autoComplete method
geocoder.autoComplete(
"Louvre",
OnlineSearchFilter("fr", position = GeoPoint(2.38305, 48.902475)),
object : SearchCallback {
override fun onSuggestions(suggestions: List<AutocompleteResult>, error: Error?) {
Log.d(
TAG,
"onSuggestions called with ${suggestions.map { it.addressLabel ?: it.place }} error: ${error?.detailedMessage}"
)
}
})Note: Its currently mandatory to specify the position in the OnlineSearchFilter.
GeoDecoder
searchAround
GeoDecoder uses local map data for searching addresses around a specific location. The search can be requested with the searchAround method :
GeoDecoder.searchAround(
GeoPoint(2.38305, 48.902475),
NearbySearchFilter("fr", 50, 5, -1, false),
object : NearbySearchCallback {
override fun onResults(results: List<NearbySearchResult>?) {
if(results != null){
for(result in results){
val distanceFromPosition = result.distance //the distance in meters between the provided GeoPoint and the result
val addressLocation = result.address.location //the location of the postal address
val poiLocation = if(result.address.isPOI) result.address.POILocation else null //the location of the POI (if the result is a POI)
val poiClassID = result.address.POIClassID //the class ID of the POI (0 if its not a POI).
//The complete list of the different cartographic class IDs are available in the CartoConst class of the Map module.
}
}else{
//no result
}
}
})You can find more details about the NearbySearchResult in the API reference.
If you want to search for EV stations, use an EvSearchFilter :
GeoDecoder.searchAround(GeoPoint(2.38305, 48.902475), EvSearchFilter(
evProfile = null, //you can pass an EvProfile to filter the results on the electric vehicle characteristics (to get only EV stations that are available for the vehicle). See the documentation of the Vehicle Manager module for more details.
language = "fr",
maxRadius = 10000L
), callback = object : NearbySearchCallback {
override fun onResults(results: List<NearbySearchResult>?) {
if (stations == null) {
//no stations available that matches with the given EvSearchFilter
} else {
for (station in stations) {
if(station is NearbyEVSearchResult){ //smart cast
val chargingPoints = station.compatibleChargingPoints //Get all charging points of the station that are compatible with the passed EV profile in the EvSearchFilter.
val nbEffectiveChargingPoints = station.nbEffectiveChargingPoints //the total number of charging points of the station, compatible or not
for(chargingPoint in chargingPoints){
val accessibility = chargingPoint.accessibility //see the full list in AccessibilityType enum
val authentication = chargingPoint.authentication //list of the authentication type of the charging point. See the full list in AuthenticationType enum
val bookingType = chargingPoint.booking //can define if the charging point can be booked (if the info is available)
val payment = chargingPoint.payment //all payment type available for this charging point. See the full list in PaymentType enum
val maxPower = chargingPoint.maxKWPower //the maximum power available for this charging point in kW
val connectors = chargingPoint.connectors //all connectors of the charging point
for(connector in connectors){
connector.type //the connector type
connector.currentType //the current type of the connector
connector.power //the power of the connector in hW
connector.kWPower //the power of the connector in kW
}
}
}
}
}
})mapMatch
Performs a map-matching process for a specified type of vehicle. Map-matching consists of correcting uncertainties related to GPS measurements by repositioning a vehicle on most accurate segment of neighboring roads.
The Waypoint objects in result will contain useful information for the Navigation, like the angle of the point, which can be used to start a Navigation using the point angle (SeeRouteOptions.useStartAngle in Navigation module documentation).
You can pass a list of mixed GeoPoint and Waypoint objects.
The result will return a list of MapMatchedPointResult that'll always contain the source GeoPoint object, the resulting Waypoint if the map-matching was successful, and the Address if the map-matching was successful and if getAddresses parameter was set to true.
GeoDecoder.mapMatch(TranspMode.PASSENGER_CAR, waypointList, object : MapMatchedPointCallback {
override fun onResult(matches: List<MapMatchedPointResult>, matchCount: Int) {
// Use the map-matched points
// i.e. create a RoutePlan
if(matches != null){
for(match in matches){
// The same GeoPoint used for the mapmatching
val sourceGeopoint = match.sourceGeopoint
// The Waypoint object if the mapmatching was successfull, null otherwise
val mapMatchedWaypoint = match.mapMatchedWaypoint
// The Address if the mapmatching was successfull and if getAddresses was set to true, null otherwise
val postalAddress = match.postalAddress
}
}
override fun onError(error: Error) {
// Handle error
}
}, true)mapMatchCircuitWaypoints
Performs map-matching specifically designed for Circuit Navigation waypoints.
Other mapMatching methods must not be used for Circuit Navigation.
The map-matched waypoints can then be used with the Planner module to create a circuit route for use with Circuit Navigation (see Navigation module documentation).
The recommended values for Waypoint radiuses in circuit navigation are:
Waypoint.radius = 2Radius used in navigation, should not be 0.Waypoint.alertRadius = 20Radius of the alert, should not be too high to avoid being alerted too soon (onViaReachedlistener is called).
import com.benomad.msdk.geocoder.GeoDecoder
import com.benomad.msdk.planner.waypoint.Waypoint
import com.benomad.msdk.navigation.TranspMode
// List of waypoints defining your circuit path
// Each waypoint can optionally contain an offroadPolyline for offroad sections
val circuitWaypoints: List<Waypoint> = listOf(
Waypoint(GeoPoint(2.38305, 48.902475)),
Waypoint(GeoPoint(2.38405, 48.903475)),
// ... more waypoints defining the circuit
)
GeoDecoder.mapMatchCircuitWaypoints(
transportationMode = TranspMode.EMERGENCY,
waypoints = circuitWaypoints,
callback = object : MapMatchedPointCallback {
override fun onResult(matches: List<MapMatchedPointResult>, matchCount: Int) {
// Use the map-matched circuit waypoints
if (matches.isNotEmpty()) {
for (match in matches) {
// The original waypoint used for map-matching
val sourceGeopoint = match.sourceGeopoint
// The map-matched waypoint if successful, null otherwise
val mapMatchedWaypoint = match.mapMatchedWaypoint
}
// Create a circuit route using the Planner module
// val routePlan = RoutePlan(...)
// val circuitRoute = Planner.computeRoute(routePlan)
// Then start circuit navigation with the route
// CircuitNavigation.getInstance().startSession(...)
// Check for a complete exemple in Navigation module
}
}
override fun onError(error: Error) {
// Handle error (e.g., GeoDecoder is busy, unexpected error)
}
},
startUTurnThreshold = 3000 // Distance in meters for U-turn detection at circuit start (default: 3000m)
)Parameters:
transportationMode- The vehicle type for map-matching (affects how waypoints snap to roads)waypoints- List of waypoints defining the circuit (can include offroad polylines)callback- Callback receiving map-matched results or errorsstartUTurnThreshold- Distance threshold in meters for detecting U-turns at the circuit start point (default: 3000m). This helps properly identify when the driver completes a lap and returns to the starting position.
Note: This method will return an error if the GeoDecoder is already busy with another operation. The matchCount parameter in the callback indicates how many waypoints were successfully map-matched.