Getting Longitude & Latitude for a address using Play Framework 2.1 WS API


This blog post serves the two purposes :

First , We’ll learn about getting the latitude & longitude for an address using Google Geocoding API.

Second , We’ll do the same as mentioned above using Play 2.1 WS API & learn about how to call the web services in Play 2.1.

On order to call the other HTTP services within Play 2.1 we use play.api.libs.ws.WS library. Calls made by using this returns scala.concurrent.Future[play.api.libs.ws.Response].

In order to get the Latitude & Longitude for a address we need to have a GET call with the following query parameters.

- address -> For which the latitude & longitude is required.
- sensor – Indicates whether or not the geocoding request comes from a device with a location sensor. Should be true here

Lets do the same by using Play 2.1 WS API.

Our GET call would looks like

WS.url("http://maps.googleapis.com/maps/api/geocode/json?address=NewDelhi&sensor=true").get()

As mentioned above the result of this GET cal would give us scala.concurrent.Future[play.api.libs.ws.Response] & we’ll map over it to get the results. The code stuff is below :

def fetchLatitudeAndLongitude(address: String): Option[(Double, Double)] = {
    implicit val timeout = Timeout(50000 milliseconds)
    
    // Encoded the address in order to remove the spaces from the address (spaces will be replaced by '+')
    //@purpose There should be no spaces in the parameter values for a GET request
    val addressEncoded = URLEncoder.encode(address, "UTF-8");
    val jsonContainingLatitudeAndLongitude = WS.url("http://maps.googleapis.com/maps/api/geocode/json?address=" +      
    addressEncoded + "&sensor=true").get()
   
    val future = jsonContainingLatitudeAndLongitude map {
      response => (response.json \\ "location")
    }

    // Wait until the future completes (Specified the timeout above)

    val result = Await.result(future, timeout.duration).asInstanceOf[List[play.api.libs.json.JsObject]]
    
    //Fetch the values for Latitude & Longitude from the result of future
    val latitude = (result(0) \\ "lat")(0).toString.toDouble
    val longitude = (result(0) \\ "lng")(0).toString.toDouble
    Option(latitude, longitude)
  }

Lets us elaborate the process step by step :

- We’ve specified the timeout for the Future , within this duration the results from the future would be expected. (Line-2)

- Made a WS GET call with the query parameters which are address & sensor. (Line -7 )

- Let the future calculate the results & wait for the specified timeout duration. (Line 10 & 16 )

- Fetched the values of Latitude & Longitude from the result of future. (Line 19-20)

Now we are ready with our WS GET call to Google Geocoding API in order to get the latitude & longitude for the given address. Lets call the method from our Global.scala when the application starts.

override def onStart(app: Application) {
    Logger.info("Application has started.........!!!!!!")
    FetchLatitudeAndLongitudeUtil.fetchLatitudeAndLongitude("New Delhi")
  }

Here’s the output when the application starts :

We’ve used WS GET call to serve our purpose. A WS POST call looks like :

 WS.url("URL").post(Map("key" -> Seq("value")))

More on Play 2.1.0 WS API .

Code for the above example can be found on Github as well.

About Neelkanth Sachdeva

Software Consultant @ Knoldus Software LLP Co-Founder @ My Cell Was Stolen
This entry was posted in Scala and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s