The widespread dominance of location-based services continues to improve user experience through customized offerings, improve operational processes through increased convenience and of course helps our lives much more easier. Today, the use of city maps even feel nostalgic and touristic. From the taxi services to the everyday go-to places, we rely on location services.
On the other hand, it often becomes overwhelming for developers when it comes to adding location data to applications. To effectively implement and achieve successful integration, developers find themselves dealing with multiple APIs for their application needs and user locations, not to mention the huge amount of time and effort spent in the process.
AWS recently introduced the fully managed Amazon Location Service in the preview version, which enables secure and easy location data integration to applications, in a cost-effective manner. Amazon Location provides location-based services such as maps, points of interest, geocoding, tracking, geofences etc. through location data brought from its trusted providers, namely Esri and HERE. This way, developers can ensure that they are able to integrate qualified location data into their applications without the high cost of custom development efforts.
The service increases convenience of developing custom applications with location data with native AWS services such as monitoring and event triggers easily, quickly and securely. Amazon Location is currently available as preview in US-East (N. Virginia and Ohio), US-West (Oregon), EU (Ireland) and Asia Pacific (Tokyo) regions.
While the service is in Preview, there is no charge per use except the supporting services such as Amazon CloudWatch, AWS Lambda, etc. Following the Preview version, the pricing will be based on the different usage types, namely Request-Based usage, Mobile Asset Tracking usage and Mobile Asset Management usage, the latter 2 involving the tracking and routing options of the mobile assets your business have operational control over. Please check the pricing page for further details here
Besides the cost and operational performance advantages of this cloud-native service, the most important thing about this service is the focus on location data privacy and advanced security. With Amazon Location Service, you no longer have to rely on the third party location-based service providers for the location information queries and requests and share your valuable sensitive information.
Amazon Location Service, as a strong alternative to well-known location-based service providers including Google Maps, ensures that all your location information and requests are anonymized, such that only required parameters are sent to location data providers while remaining account information, user data etc. are kept private. Your AWS account information never leaves your own account, while the transmitted parameters are being encrypted. This way, your location data isn’t shared with any other third parties to be collected, stored and processed for additional purposes other than your request processing. What this means is that you are in control of your sensitive information and your strategic data is secured.
Amazon Location provides various resources with dedicated APIs to be accessed through requests. These resources are namely Map, Place Index, Routes (soon to be launched), Geofence Collection and Tracker. You simply create the resources you need for your application in your AWS account and then call the resources’ own APIs to make location requests.
The map resource enables you to use maps brought from your selected data provider in your applications with consistent APIs. To add a geographical search engine to your applications, you can simply create a Place Index resource and enable geocoding/reverse geocoding. What is more, you can create boundaries within your maps with the Geofence Collection resource and create custom events to be triggered based on these geofences. You can also use Tracker resource to store location updates from devices, submit location updates and query for location data with the associated API. When combined with Geofencing, you can use Tracker resources to collect and evaluate location data in line with your selected geofences. Last but not least, the upcoming Routes resource will enable users to request directions, time and distance information between distinct locations.
While the easy access to qualified global location data from trusted sources help you to reduce development time and effort, Amazon Location Service integration with various native AWS services also enables you to develop your custom applications in a fully cloud-native environment. The service includes built-in Amazon CloudWatch metrics for you to monitor location requests and events. Amazon Location Service is also integrated with Amazon EventBridge, in which you can create your own event-driven architecture that responds to and takes actions according to location data with the AWS Lambda functions.
The service enables you to develop custom applications that need location data for various purposes, ranging from marketing to organizational asset management. For example, you can enable your application to send custom marketing offerings to your users when they are nearby the store with the geofence settings, send alerts to users when delivery is near them, or even track your organizational mobile assets for the shipment, delivery and optimizing the best route.
Before we dive into examples, we need to talk about a few core concepts.
Authentication
First of all, all AWS resource accesses need authentication. They are accessed via IAM, Cognito, or role assumptions. So, in order to access Amazon Location Service API’s in our applications, we need to create a Cognito unauthenticated identity pool. Go ahead to Amazon Cognito from Management Console, click Create new identity pool
. Type a name and check Enable access to unauthenticated identities
. This will allow users to access resources via guest authentication. Add authenticated and unauthenticated roles, click Create. After that, go ahead to IAM Console, click Roles
and find your unauthenticated role. Click to your role, and Attach Policy, then Create policy. In Create Policy page, pick Location from services. I will be using the same role to access all resources that I create, therefore I will be picking Read and All resources under Resources. You can limit your Actions or Resources however you want. Click Review Policy, name your policy and create it. Then go back to your Attach Permissions page, refresh and find your policy, attach it to the unauth role.
Authentication prerequisite is complete, we will need one more thing to make our experience easier while coding. Go to your Identity pool and click Edit Identity pool. Copy your Identity Pool Id. We will be using this id throughout the examples.
Renderers
In order to display a map, you need to use what AWS calls, a renderer. Renderers are basically UI components that render map tiles. Location Service has a few popular libraries as well as AWS SDK’s available as renderers, which we will cover now.
Let’s start with a simple example, one of the most popular implementations of location today, embedding a map to your company’s website that shows exact location with a pin. Let’s create a basic html page, a div to show the map. Amazon Location Service has options on which component do you want to use to render your map, you can use Amplify’s new Location component, Mapbox GL or Tangram. I will be using the popular Mapbox GL library. Let’s add Mapbox GL js and css, AWS SDK and Amplify Core (to sign our requests).
<!-- CSS dependencies -->
<link
href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css"
rel="stylesheet"
/>
<!-- JavaScript dependencies -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.775.0.min.js"></script>
<script src="https://unpkg.com/@aws-amplify/[email protected]/dist/aws-amplify-core.min.js"></script>
<script>
// application-specific code
</script>
Now go ahead to Console, and open Location Services. Click Maps on left and create a map resource. I’ve named my resource’s name as SufleOfficeMap, I’m planning to pin Sufle’s office location. Under Maps, we are presented with a few different options of maps.
I’ve picked Esri Light option. Click Create Map. Now let’s add your map to your html page. We will need our identity pool id. Start by initializing AWS SDK and making sure your authentication cycle works out of the box.
// Cognito Identity Pool ID
const identityPoolId = "<region>:<identity-pool-id>";
// Amazon Location Service Map name
const mapName = "SufleOfficeMap";
AWS.config.region = identityPoolId.split(":")[0];
// instantiate a Cognito-backed credential provider
const credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: identityPoolId,
});
async function refreshCredentials() {
await credentials.refreshPromise();
// schedule the next credential refresh when they're about to expire
setTimeout(refreshCredentials, credentials.expireTime - new Date());
}
Since we are using AWS SDK within the browser, this piece of code will make sure that you have access when you are accessing your resources while you are in the page. Next, we need to use Mapbox GL’s transformRequest option to modify and sign our requests that are made to Location Service. We will use Amplify Core’s Signer to sign requests with Signature Version 4.
// use Signer from @aws-amplify/core
const { Signer } = window.aws_amplify_core;
/**
* Sign requests made by Mapbox GL JS using AWS SigV4.
*/
function transformRequest(url, resourceType) {
if (resourceType === "Style" && !url.includes("://")) {
// resolve to an AWS URL
url = `https://maps.geo.${AWS.config.region}.amazonaws.com/maps/v0/maps/${url}/style-descriptor`;
}
if (url.includes("amazonaws.com")) {
// only sign AWS requests (with the signature as part of the query string)
return {
url: Signer.signUrl(url, {
access_key: credentials.accessKeyId,
secret_key: credentials.secretAccessKey,
session_token: credentials.sessionToken,
}),
};
}
// don't sign
return { url };
}
We will be signing only requests that are going to amazonaws.com. Finally, it is time to initialize our map!
async function initializeMap() {
// load credentials and set them up to refresh
await credentials.getPromise();
// actually initialize the map
const map = new mapboxgl.Map({
container: "map",
center: [29.0085436, 41.0797291],
zoom: 17,
style: mapName,
transformRequest,
});
}
One different thing from our used-to map experiences is that Mapbox GL takes longitude-latitude then latitude longitude. But, voila! We have our map with the location. Now let’s add a marker with a popup.
var marker = new mapboxgl.Marker()
.setLngLat([29.0085436, 41.0797291])
.setPopup(
new mapboxgl.Popup({ offset: 25 }).setHTML(
"<img style='max-width: 80px;' src='https://www.sufle.io/img/logo.svg' />"
)
)
.addTo(map);
Now let’s try searching for places by text. We need to go to Amazon Location Service and create a Place index. Go ahead and click Create place index
.
Enter a name, and choose a service to provide indexes. I’m picking Place index by Esri, I’m just testing it out. As I’m not planning to store any results, I’ll choose No, single use only.
, click Create place index.
Let’s add AWS SDK and add an input to the page. We need to add the same authentication cycle, since we will be using credentials to access the Location Service now. We’ve also added our place index’s name to use in our code.
const placeIndex = "SearchPlaceIndex";
const locationService = new AWS.Location({
credentials,
region: identityPoolId.split(":")[0],
});
window.onload = () => {
const input = document.getElementById("search-input");
const results = document.getElementById("results");
input.addEventListener(
"change",
_.debounce((e) => {
locationService.searchPlaceIndexForText(
{
IndexName: placeIndex,
Text: input.value,
},
(err, response) => {
if (err) {
console.error(err);
} else {
results.innerHTML = "";
response.Results.forEach((place) => {
let placeElement = document.createElement("p");
placeElement.textContent = place.Place.Label;
results.appendChild(placeElement);
});
}
}
);
}, 500)
);
};
I’ve added a basic input listener and rendered a list to see what are results.
When we check the response, it does not only include places, but also many properties related to the place. Furthermore there’s a Summary
that shows DataSource
and a ResultBBox
property which gives you 4 points to limit your rendered map to that search result.
Since we’ve gathered our place information that includes geometry data, let’s jump into Geocoding.
I will add a map functionality to the search results that we’ve gathered from our places search. Also let’s bring Mapbox GL and Amplify Core libraries back.
We need to get geometry data of results and change our map according to that, we can already access it via Place.Geometry.Point. Since we have that data, we can write rest of it pretty easily:
function updateMap(place) {
map.flyTo({
center: place.Geometry.Point,
essential: true,
});
if (currentMarker) {
currentMarker.remove();
}
currentMarker = new mapboxgl.Marker()
.setLngLat(place.Geometry.Point)
.setPopup(
new mapboxgl.Popup({ offset: 25 }).setHTML(
"<p>" + place.Label + "</p>"
)
)
.addTo(map);
}
window.onload = () => {
const input = document.getElementById("search-input");
const results = document.getElementById("results");
input.addEventListener(
"change",
_.debounce((e) => {
locationService.searchPlaceIndexForText(
{
IndexName: placeIndex,
Text: input.value,
},
(err, response) => {
if (err) {
console.error(err);
} else {
results.innerHTML = "";
console.log(response);
response.Results.forEach((place) => {
let placeElement = document.createElement("a");
placeElement.style.width = "100%";
placeElement.style.display = "block";
placeElement.onclick = () => {
updateMap(place.Place);
};
placeElement.textContent = place.Place.Label;
results.appendChild(placeElement);
});
}
}
);
}, 500)
);
};
I’ve also added the updateMap function to update the map according to the selected location. I’ve used .flyTo
method to make it more fancy:
One of the most popular usage of Places and Maps services is reverse geocoding. While geocoding is searching and transforming through text to location, reverse geocoding does exactly the reverse, searching addresses that are at the position. Amazon Location Service API has a SearchPlaceIndexForPosition
method that we can pass a Position. Let’s try it!
We need to create a marker by default and make it draggable. When drag ends, we can get it’s latitude and longitude, then send it to the service. Don’t forget that we need to use our Place index when calling this service, too.
let map = null;
let draggableMarker = null;
async function initializeMap() {
// load credentials and set them up to refresh
await credentials.getPromise();
// actually initialize the map
map = new mapboxgl.Map({
container: "map",
center: [29.0085436, 41.0797291], // initial map centerpoint
zoom: 17, // initial map zoom
style: mapName,
transformRequest,
});
draggableMarker = new mapboxgl.Marker({
draggable: true,
})
.setLngLat([29.0085436, 41.0797291])
.addTo(map);
draggableMarker.on("dragend", () => {
const results = document.getElementById("results");
var lngLat = draggableMarker.getLngLat();
locationService.searchPlaceIndexForPosition(
{
IndexName: placeIndex,
Position: [lngLat.lng, lngLat.lat],
},
(err, response) => {
if (err) {
console.error(err);
} else {
results.innerHTML = "";
response.Results.forEach((place) => {
let placeElement = document.createElement("a");
placeElement.style.width = "100%";
placeElement.style.display = "block";
placeElement.style.fontSize = "30px";
placeElement.textContent = place.Place.Label;
results.appendChild(placeElement);
});
}
}
);
});
}
initializeMap();
That's pretty much it. As in any AWS Service that has been released, there was a learning curve in the beginning. Once you are familiar with it, it is very helpful and easy to implement. You can find all example codes at Github.
Examples about Amazon Location Service.
github.com/sufleio/amazon-location-service-examplesGeofencing testing in Explore tab looks very exciting, but demoing a geofencing application, handling events and adding geomarketing features are whole another post's topic. We're planning to deep dive into the Location Service and see what it may bring in near future. Stay tuned!
An experienced software engineer, Durul is indeed a technology lover and always excited to see and learn what technology offers. With his experience in startups from Entertainment to SaaS, he is keen on sharing his experience with the technology community.
Subscribe to Our Newsletter
Our Service
Specialties
Copyright © 2018-2024 Sufle
We use cookies to offer you a better experience with personalized content.
Cookies are small files that are sent to and stored in your computer by the websites you visit. Next time you visit the site, your browser will read the cookie and relay the information back to the website or element that originally set the cookie.
Cookies allow us to recognize you automatically whenever you visit our site so that we can personalize your experience and provide you with better service.