Geocoding

The Geocoding service provides three methods related to converting street addresses to/from longitude and latitude coordinates. ALKMaps.Map class also provoides three wrapper methods. By calling the wrapper methods, region will be inherited from baseLayer region parameter if user does not supply region value. The wrapper functions also take in and return any coordinates in the same projection as the map.

Geocoding

Geocoding allows you to retrieve longitude and latitude coordinates for a given address. Geocoding is done by making a call to the ALKMaps.Geocoder.geocode method. The geocode method takes two primary parameters. First is an address object. The second and third parameters, success and failure, are callback functions for the asynchronous response. If the geocoding service finds multiple results that match the address object, by default, the best match is returned. To receive multiple results set the optional listSize property to the desired amount.

The response from the geocode method is an array JavaScript objects that contains the longitude and latitude coordinates for the address if the address could be resolved. In addition, the object contains a normalized address object as well as an array of error/warning messages.

ALKMaps.Geocoder.geocode({
	address:{
		addr: "1000 Herrontown Road", 
		city: "Princeton", 
		state: "NJ", 
		zip: "08540",
		region: "NA" //Valid values are NA, EU, OC, SA, AS, AF, and ME. Default is NA.
	},
	listSize: 1, //Optional. The number of results returned if the geocoding service finds multiple matches.
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});

                

//map wrapper function call: (region inherited from baseLayer)
map.geocode({
	address:{
		addr: "1000 Herrontown Road", 
		city: "Princeton", 
		state: "NJ", 
		zip: "08540"
	},
	listSize: 1,
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});

                    

By default, geocoding calls are done asynchronously and the results are returned through callback functions. This means you will need to wait for the results to return before attempting the use the geocoded locations. See Dealing With Multiple Asynchronous Geocoding Requests for more information.

If you are a global highway customer that would like to use geocoding in other regions, you can set dataset to "Current" inside of the address parameter to use global highway data.

Coords

The Coords property of the response contains an object with a Lon property and a Lat property. The coordinates returned by the previous example can be accessed from inside the success callback function in the following manner:

var geocodedLongitude = response[0].Coords.Lon;  //-74.654726
var geocodedLatitude =  response[0].Coords.Lat;  //40.38825

Address

The Address property of the response contains an object with properties for:

  • StreetAddress
  • City
  • County
  • State
  • Zip

Errors

The Errors property of the response contains an array of error message objects. Each object has a Description property that describes the error.

Reverse Geocoding

Reverse Geocoding allows you to retrieve the nearest address for given longitude and latitude coordinates using the ALKMaps.Geocoder.reverseGeocode method. Like the geocoding method, if async is set to true you should provide success and failure callbacks.

var reverseGeocodedLocation = ALKMaps.Geocoder.reverseGeocode({
	lonLat: new ALKMaps.LonLat(-122.31693, 47.60784), 
	region: "NA", //Valid values are NA, EU, OC, SA, AS, AF, and ME. Default is NA.
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});
                    

//map wrapper function call: (region inherited from baseLayer)
var reverseGeocodedLocation2 = map.reverseGeocode({
	lonLat: new ALKMaps.LonLat(-122.31693, 47.60784).transform(new ALKMaps.Projection("EPSG:4326"), map.getProjectionObject()),
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});
					

The response is an array of objects containing the same structure as the geocode method reponse. For the reverseGeocode scenario, the Address and Errors properties will be the ones of interest.

If you are a global highway customer that would like to use reverse geocoding in other regions, you can set the dataset parameter to "Current" to use global highway data.

Simple Geocoding

The simple geocoding method takes the same input as the geocode method but returns an instance of ALKMaps.LonLat containing the geocoded coordinates.

var simpleGeocodedLocation = ALKMaps.Geocoder.simpleGeocode({
	address:{
		addr: "1000 Herrontown Road", 
		city: "Princeton", 
		state: "NJ", 
		zip: "08540",
		region: "NA" //Valid values are NA, EU, OC, SA, AS, AF, and ME. Default is NA.
	}, 
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});

var simpleGeocodedLongitude = simpleGeocodedLocation.lon;  //-74.654726
var simpleGeocodedLatitude =  simpleGeocodedLocation.lat;  //40.38825

                         

//map wrapper function call: (region inherited from baseLayer)
var simpleGeocodedLocation2 = map.simpleGeocode({
	address:{
		addr: "1000 Herrontown Road", 
		city: "Princeton", 
		state: "NJ", 
		zip: "08540",
		region: "NA"
	}, 
	success: function(response){
		console.log(response);
	},
	failure: function(response){
		alert(response.status + "\n" +response.statusText + "\n" + response.responseText);
	}
});
					

If you are a global highway customer that would like to use geocoding in other regions, you can set dataset to "Current" inside of the address parameter to use global highway data.

Geolocation

The Geolocate control uses the Geolocation API provided by modern web browsers to retrieve the approximate location of the browser. The functionality of this control is dependent on both the browser supporting the Geolocation API and the user granting access to their location.

For more information, see the Geolocate control.

Dealing With Multiple Asynchronous Geocoding Requests

When creating routes, it's often necessary to geocode multiple addresses before generating the route. Due to the asynchronous nature of the requests, you will have to wait until all the requests have returned before you can make the addRoute call.

Nested Callbacks

One way to accomplish this is to nest the callbacks of each request to guarantee each address is geocoded before the next is attempted. This approach can work for small routes but can become very cumbersome for large routes.

var address1, address2;

ALKMaps.Geocoder.simpleGeocode({
	address: { zip: "19103" },
	success: function(response){
		address1 = response;
		
		ALKMaps.Geocoder.simpleGeocode({
			address: { zip: "08401" },
			success: function(response){
				address2 = response;

				routingLayer.addRoute({
					stops: [
						address1, 
						address2
					],
					
					...

				});
			
			},
			failure: function(response){
				...
			}
		});
	},
	failure: function(response){
		...
	}
});

Promise Pattern

One alternative to reduce the complexity of nested callbacks is the Promise pattern. JavaScript libraries like jQuery and Dojo make available implementations of the Promise pattern. Here is the previous example rewritten with the aid of jQuery Deferred/Promise functions.

var address1Promise = $.Deferred(function(d){
	ALKMaps.Geocoder.simpleGeocode({
		address: { zip: "19103" },
		success: d.resolve,
		failure: d.reject
	});
}).promise();

var address2Promise = $.Deferred(function(d){
	ALKMaps.Geocoder.simpleGeocode({
		address: { zip: "08401" },
		success: d.resolve,
		failure: d.reject
	});
}).promise();

$.when(address1Promise, address2Promise).then(function(address1, address2){
	routingLayer.addRoute({
		stops: [
			address1, 
			address2
		],

		...

	});
});

For large routes, the Promise creation can be refactored into a separate function to reduce the duplication.