A primer on using the Google Maps Platform
Maps is my favorite Google product. The application is very well designed, loaded with features, highly performant, and does not have a decent alternative. Along with the consumer-facing Maps product, Google Maps Platform has also provided us with a list of APIs that gives access to most of the data that Google Maps holds. The data returned by these APIs can be used to build applications such as ridesharing apps, logistics solutions, etc.
In this post, I shall show the usage of some of the Google Maps APIs. I shall be using Oracle APEX to build the application that makes use of these APIs. The examples that I am detailing below are basic examples to get you started working with these APIs. The documentation on Google Maps Platform will provide all the finer details on query parameters, quota limits etc.
Registering a new API key
In order to work with Google Maps Platform, the first thing you need is a project set up in Google Cloud. You can follow the tutorials provided there to set up a project and get started.
Once, you have a project running, under APIs and Services, there is a page called Credentials. Use this feature to create an API key for your application. The API key is the "access code" that you need to show Google any time you want to make use of any of the APIs. Google tracks information about your service usage against the key. This information is used to determine what to charge you for the usage of the various services and also to check if your usage is exceeding pre-determined limits.
You can also add additional restrictions to your API key. You can tell Google that this key would be used only inside an iPhone app or used only from a browser. You can also tell Google to consider the key valid if the request comes only from a list of pre-determined services. You can also restrict the usage of the API key to a restricted list of services (APIs).
If you are using Oracle APEX to invoke the APIs, and you want Google to respond to requests only from your APEX application, then you can specify the URL of your APEX has shown below.
Now let's start looking at some of the APIs in detail.
Maps Embed API
The Maps Embed API lets you place an interactive Google Map in your HTML page as an iframe. In order to use this API, you first need to allow the usage of this API against your API key.
On a blank page, I created a new Static Content region and named it Embed Maps. In the Source section, I added the code for the iframe container.
This sample code below will search for Oracle Headquarters in Redwood City and display the location with a pin. Make sure you replace the ENTER-YOUR-API-HEY-HERE with the API key that you created earlier in this walkthrough.
<iframe
width="600"
height="450"
frameborder="0" style="border:0"
src="https://www.google.com/maps/embed/v1/place?key=ENTER-YOUR-API-KEY-HERE&q=Oracle+Headquarters,Redwood+City,CA" allowfullscreen>
</iframe>
The output will look like this.
Autocomplete with Places API (Maps Javascript API, Places API)
When entering your address in an address field in forms in websites, have you noticed how the address field starts recommending addresses based on what you are typing? On the Google Maps Platform, this feature is known as Autocomplete. Using this functionality, you can enable a field on your Oracle APEX page (or any web page for that matter), to automatically start showing address suggestions based on user entry.
To do this, associate Maps Javascript API and Places API with your API key in Google Cloud.
I will now walk through the steps to add this to an Oracle APEX page.
Step 1: Page items. We create a new Static Content region and in the region, we add the following page items
1. A Text Field item named P2_SEARCH (the field where the user searches for an address)
2. A Text Field item named P2_PLACE_ID (this will store the Google Place Id for the address)
3. A Text Field item name P2_FORMATTED_ADDRESS (this will store the formatted address)
Step 2: Region. Create a new Static Content region, name it Autocomplete Map, and place it right next to the one that we created in the previous step. We achieve this positioning/layout by unchecking the "Start New Row" attribute for this new region. In the Source region, add the following code.
<iframe id="gmapiframe"
width="450"
height="450"
frameborder="0" style="border:0"
src="https://www.google.com/maps/embed/v1/place?key=ENTER-YOUR-API-KEY-HERE&q=Oracle+Headquarters,Redwood+City,CA"
allowfullscreen></iframe>
Step 3: Load libraries and JS. For the autocomplete feature to work well, we need to load some JavaScript from Google. To do this, add the following addresses in the File URLs field of the page.
https://maps.googleapis.com/maps/api/js?key=ENTER-YOUR-API-KEY-HERE&libraries=places
Step 4: Create variables and functions. Add the following code into the Function and Global Variable Declaration field right underneath the File URLs field. The variable autocomplete would be used later to hold a Google Maps object. The function when invoked will read information about the place from the autocomplete object and load the values of Place Id and Formatted Address into the text fields that we have created. Also, we will update the source URL in the Embed Map created in the Autocomplete Map region so that it will show us the place contained in the autocomplete object.
var autocomplete;
function fillInAddress() {
var place = autocomplete.getPlace();
if(place !== undefined) {
document.getElementById('P2_PLACE_ID').value = place.place_id;
document.getElementById('P2_FORMATTED_ADDRESS').value = place.formatted_address;
document.getElementById('gmapiframe').src = "https://www.google.com/maps/embed/v1/place?key=ENTER-YOUR-API-KEY-HERE&q=place_id:"+place.place_id;
}
}
Step 5: Initialize the autocomplete object. When the page loads, we want the autocomplete object to be initialized with some information. We pass our P2_SEARCH page item to the Autocomplete object. This tells Google that whenever someone starts typing into the field, Google needs to start showing address suggestions. Google holds abundant information about addresses and places in its Maps platform. We then tell Autocomplete that we are interested only in the place_id and formatted_address information. We then add a listener for the place_changed event. The listener will invoke the fillInAddress function whenever the place_changed event is triggered. Add the following code to the Execute When Page Loads field.
autocomplete = new google.maps.places.Autocomplete(document.getElementById('P2_SEARCH'));
autocomplete.setFields(['place_id', 'formatted_address']);
autocomplete.addListener('place_changed', function () {fillInAddress()});
Voila! That's it! Here's what it looks like in action!
Another common requirement is to fetch the latitude and longitude information about addresses. To fetch this, pass the value geometry when invoking setFields function in the autocomplete object. This is the code that we added in the Execute When Page Loads section.
autocomplete.setFields(['place_id', 'formatted_address', 'geometry']);
Once that's in place, create two page-items, one to capture the latitude and another one to capture the longitude. Then add the following code to fetch these values from the object returned by Google Maps, and set it into your page items. This was in the Function and Global Variables Declaration section.
document.getElementById('YOUR-PAGE-ITEM-NAME').value = place.geometry.location.lat();
document.getElementById('YOUR-PAGE-ITEM-NAME').value = place.geometry.location.lng();
Distance Matrix API
This API gives you distance and time information between two sets of addresses. You send a request with a set of "origin" addresses and a set of "destination" addresses. The API will return the distance between each address in the origin set and each address in the destination set.
Consider the following table of addresses. The value in the brackets is the Google Place Id for the address.
I have written a small anonymous block in PL/SQL to invoke the Distance Matrix API for these addresses. I have split the API request URL into separate VARCHAR2 variables so that it's easy to understand.
lc_api_end_point - this is the endpoint URL of the API. Enter your Google API key here.
lc_origins - this is the set of addresses from where you need the distance to each of the destinations. You can pass the address in other formats as well (such as latitude and longitude. In the example, I use place id).
lc_destinations - this is similar to lc_origins, but it is the set of destination addresses.
I then concatenate all this information into a single variable lc_request_url and make use of apex_web_service.make_rest_request function to make a GET request.
declare
lc_api_end_point varchar2(100) := 'https://maps.googleapis.com/maps/api/distancematrix/json?key=ENTER-YOUR-API-KEY-HERE';
lc_origins varchar2(32767) := '&'||'origins=place_id:ChIJp04_d7GAj4AR_y_dUHlPR_M|place_id:ChIJnbv6FlKHj4ARyg9u7ehaCtc';
lc_destinations varchar2(32767) := '&'||'destinations=place_id:ChIJv_7_ND5-hYAR8UBqWZ3t1Vg|place_id:ChIJlwZhkUGHj4ARgNaadWHN7tc';
lc_request_url varchar2(32767);
lclob_response clob;
begin
lc_request_url := lc_api_end_point||lc_origins||lc_destinations||'&';
lclob_response := apex_web_service.make_rest_request(
p_url => lc_request_url,
p_http_method => 'GET',
p_parm_name => apex_util.string_to_table('appid:format'),
p_parm_value => apex_util.string_to_table(apex_application.g_x01||':'||apex_application.g_x02)
);
dbms_output.put_line(lclob_response);
end;
I have requested the output in JSON format. Below is a sample output that you should expect. You can parse through the response using Oracle database JSON objects and functions such as JSON_OBJECT_T, GET_STRING, GET_ARRAY, TREAT, etc.
{
"destination_addresses" : [
"1555 40th St, Oakland, CA 94608, USA",
"3250 Lakeshore Ave, Oakland, CA 94610, USA"
],
"origin_addresses" : [
"Frank H. Ogawa Plaza, Oakland City Hall, 1 Frank H. Ogawa Plaza, Oakland, CA 94612, USA",
"230 Bay Pl, Oakland, CA 94612, USA"
],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "3.8 km",
"value" : 3824
},
"duration" : {
"text" : "8 mins",
"value" : 498
},
"status" : "OK"
},
{
"distance" : {
"text" : "5.4 km",
"value" : 5409
},
"duration" : {
"text" : "8 mins",
"value" : 482
},
"status" : "OK"
}
]
},
{
"elements" : [
{
"distance" : {
"text" : "3.9 km",
"value" : 3855
},
"duration" : {
"text" : "12 mins",
"value" : 725
},
"status" : "OK"
},
{
"distance" : {
"text" : "2.2 km",
"value" : 2183
},
"duration" : {
"text" : "7 mins",
"value" : 430
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
There are more interesting APIs available on the platform. I have used Google Maps Platform in conjunction with Oracle APEX to build the application https://routebuilder.app
Comments