Geocoding and Reverse Geocoding
Geocoding and reverse geocoding APIs from SDK for iOS allow application developers to offer search functionality for requesting NMAPlaceLocation
information. Geocoding APIs resolve a free-formatted text query to an NMAGeoCoordinates
, while reverse geocoding APIs resolve from an NMAGeoCoordinates
to geographic data such as NMAAddress
.
NMAAddress
provides textual address information including house number, street name, city, country, district, and more. It encompasses everything about an address or a point on the map. The NMAPlaceLocation
class represents an area on the map where additional attributes can be retrieved. These additional attributes include NMAAddress
, unique identifier, label, location, access locations, and NMAGeoBoundingBox
for the location.
Geocoding and Reverse Geocoding Example on GitHub
You can find an example that demonstrates this feature at https://github.com/heremaps/ (Obj-C) and https://github.com/heremaps/ (Swift).
The NMAGeocoder Interface
The NMAGeocoder
interface represents a factory class used to instantiate location search requests. Two types of requests are available: NMAGeocodeRequest
and NMAReverseGeocodeRequest
.
The NMAGeocodeRequest Interface
The NMAGeocodeRequest
interface represents an extended NMARequest
. The NMAGeocodeRequest
can be created using a combination of a search area and a free text query string. This is known as a "one-box" request. It returns NMAPlaceLocation
results according to the specified search area and text query. You can specify a search area by providing an NMAGeoBoundingBox
or a location with a search radius.
The following shows the methods used to create one-box requests:
NMAGeocodeRequest* request = [[NMAGeocoder sharedGeocoder] createGeocodeRequestWithQuery:string
searchArea:geoBoundingBox
locationContext:geoCoordinates];
NMAGeocodeRequest* request = [[NMAGeocoder sharedGeocoder] createGeocodeRequestWithQuery:string
searchRadius:radius
locationContext:geoCoordinates];
The preceding methods return an NMAGeocodeRequest
object. To perform the request, call its startWithListener:
method. The parameter of this method is an object which receives the request results; the object must implement the NMAResultListener
protocol. Once a request is invoked, it can be cancelled using cancel
method of NMARequest
, which returns a BOOL
value indicating whether the result was cancelled successfully. If the NMAGeocodeRequest
is successful, a list of NMAGeocodeResult
objects is returned to the listener.
The following code example demonstrates how to use an NMAGeocodeRequest
:
// Implementation of NMAResultListener
@interface NMAGeocodeTest : NSObject<NMAResultListener> {
}
@end
@implementation NMAGeocodeTest
// NMAResultListener protocol callback implementation
- (void)request:(NMARequest*)request
didCompleteWithData:(id)data
error:(NSError*)error
{
if ( ( [request isKindOfClass:[NMAGeocodeRequest class]]) &&
( error.code == NMARequestErrorNone ) )
{
// Process result NSArray of NMAGeocodeResult objects
[self processResult:(NSMutableArray *)data];
}
else
{
// Handle error
...
}
}
- (void) startSearch
{
NMAGeoCoordinates *topLeft =
[[NMAGeoCoordinates alloc]
initWithLatitude:52.537413 longitude:13.365641];
NMAGeoCoordinates *bottomRight =
[[NMAGeoCoordinates alloc]
initWithLatitude:52.522428 longitude:13.39345];
NMAGeoBoundingBox *boundingBox =
[NMAGeoBoundingBox
geoBoundingBoxWithTopLeft:topLeft bottomRight:bottomRight];
NMAGeocodeRequest* request = [[NMAGeocoder sharedGeocoder]
createGeocodeRequestWithQuery:@"100 INVALIDENSTRASSE"
searchArea:boundingBox
locationContext:nil];
// limit the number of results to 10
request.collectionSize = 10;
NSError* error = [request startWithListener:self];
if (error.code != NMARequestErrorNone)
{
// Handle request error
...
}
}
@end
The NMAReverseGeocodeRequest interface
The NMAReverseGeocodeRequest
interface represents an extended NMARequest
used to retrieve NMAPlaceLocation
data. The request is created using an NMAGeoCoordinates
as shown below:
NMAGeocodeRequest* request = [[NMAGeocoder sharedGeocoder]
createReverseGeocodeRequestWithGeoCoordinates:geoCoordinates];
The above method returns an NMAReverseGeocodeRequest
object. Reverse geocode requests are used in the same way as regular geocode requests (described in the previous section) but the results are returned as an array of NMAReverseGeocodeResult
objects.
The following example shows how to create and use an NMAReverseGeocodeRequest
:
// Implementation of NMAResultListener
@interface NMAReverseGeocodeTest : NSObject<NMAResultListener> {
}
@end
@implementation NMAReverseGeocodeTest
// NMAResultListener protocol callback implementation
- (void)request:(NMARequest*)request
didCompleteWithData:(id)data
error:(NSError*)error
{
if ( ( [request isKindOfClass:[NMAReverseGeocodeRequest class]]) &&
( error.code == NMARequestErrorNone ) )
{
// Process result NSArray of NMAReverseGeocodeResult objects
[self processResult:(NSMutableArray *)data];
}
else
{
// Handle error
...
}
}
- (void) startSearch
{
// Instantiate an Address object
NMAGeoCoordinates* vancouver = [[NMAGeoCoordinates alloc] initWithLatitude:49.2849 longitude:-123.1252];
NMAReverseGeocodeRequest* request = [[NMAGeocoder sharedGeocoder] createReverseGeocodeRequestWithGeoCoordinates:vancouver];
NSError* error = [request startWithListener:self];
if (error.code != NMARequestErrorNone)
{
// Handle request error
...
}
}
@end
By default the reverse geocode request above searches for the closest street address. Alternatively, you can also create a reverse geocoding request in one of the following modes (NMAReverseGeocodeMode
):
-
NMAReverseGeocodeModeRetrieveAddresses
- Search for the closest street address or addresses (same as above) -
NMAReverseGeocodeModeRetrieveAreas
- Retrieve the administrative area information for the position provided in the request -
NMAReverseGeocodeModeRetrieveLandmarks
- Search for landmarks like parks and lakes in the proximity provided in the request -
NMAReverseGeocodeModeRetrieveAll
- Search for streets, administrative areas, and landmarks. This mode aggregates the results of the previous three modes in one call -
NMAReverseGeocodeModeTrackPosition
- Retrieve street and address information based on a position and bearing
See the following for an example of how to use this type of request. Note that bearing
parameter is only used when you use NMAReverseGeocodeModeTrackPosition
.
NMAReverseGeocodeRequest* request = [[NMAGeocoder sharedGeocoder]
createReverseGeocodeRequestWithGeoCoordinates:geoCoordinates
mode:NMAReverseGeocodeModeRetrieveLandmarks
bearing:0];
[request startWithBlock:^(NMARequest *request, id data, NSError *error) {
if(!error) {
NSArray *results = (NSArray*)data;
NMAReverseGeocodeResult *result = nil;
NSMutableString *address = [NSMutableString new];
for (NSUInteger i = 0; i < results.count; i ++) {
result = [results objectAtIndex:i];
[address appendFormat:@"%ld.\n", i + 1];
if (result.distance > 0) {
[address appendFormat:@"distance:%.2f\n", result.distance];
}
if (result.location.address.houseNumber) {
[address appendFormat:@"houseNo:%@\n", result.location.address.houseNumber];
}
if (result.location.address.street) {
[address appendFormat:@"street:%@\n", result.location.address.street];
}
if (result.location.address.city) {
[address appendFormat:@"city:%@\n", result.location.address.city];
}
if (result.location.address.state) {
[address appendFormat:@"state:%@\n", result.location.address.state];
}
if (result.location.address.postalCode) {
[address appendFormat:@"postalCode:%@\n", result.location.address.postalCode];
}
if (result.location.address.countryName) {
[address appendFormat:@"country:%@\n", result.location.address.countryName];
}
if (result.location.timeZone) {
[address appendFormat:@"timeZone:%@\n\n", result.location.timeZone.name];
}
}
}
}];
Offline Geocoding
Applications developed with SDK for iOS can perform offline geocoding, which allows geocode and reverse geocode requests to be performed without an active data connection. This is done automatically when an active data connection is not available as long as the map and database information has been previously downloaded. When a data connection is available, HERE SDK attempts to perform the request online first.
For more information about the APIs introduced and demonstrated in this section refer to the API Reference documentation.