Fetching Google Maps search results with Java

Spanish

I’m recently working on an Android project which lists the gas stations around your current location (based on the GPS coordinates). The idea was simple, take the GPS values, use Google’s APIs or the Search protocol  to get the output as an XML and display the values according to my needs. However, I found out  it was not so easy; in order to use Google’s  APIs, you have to pay a fee  (or you can do it for free, but you will be limited by the number of transactions per day). The search protocol was an option, but you also have to pay for it if you want to get the result as an XML.

So, I played around with Google’s search parameters and I found out that you can get the output as a JSON string. The following document explains how to send your search request to Google, get the JSON response and how to parse it to build a Java object.

The following libraries and applications are used:

- Windows 7

- Eclipse Galileo

json-lib-2.4-jdk15

- ezmorph-1.0.6

- Apache commons (commons-beanutils-1.8.3, commons-collections-3.2, commons-lang-2.3, commons-logging-1.0.4).

1) CODING THE SOLUTION

1.1) First, you need to build a Java project. You can name it whatever you want, I called it GoogleMapSearch2JSON:

image

1.2) Next, create a new Java class and call it JsonConverter:

image

The first thing you have to do, is to write the code that will send the GET request and fetch the response. The below URL will be called by this code:

http://maps.google.com/maps?f=q&source=s_q&output=json&start=0&q=yourquery

There are two parameters that you have to modify. The  first one, is the output value (don’t bother to change it to xml, it won’t work); the second parameter is the query that you are passing to Google. If you type this URL in your browser (you can use whatever address you want for the query parameter), a file will be downloaded; open it in notepad and you should see something like this:

image

As you  can see, this is a JSON string of your search result. However, if you try to open it using a JSON client you will get an error. It is caused by the while(1); string found at the beginning of the file. Remove the string, save the file and open it again using your JSON viewer and you should get this:

image

Most of the information displayed is not useful (at least for me); the results returned by the search will be found in OVERLAYS –> MARKERS. Each marker represents one place:

image

And each marker object contains all the information related to the place. Like name, address, latitude, longitude, phone number, etc.

1.3) The next step is to code the method that will do all the processing automatically. To achieve this, the URL and URLConnection classes are used. Add a new public method called mapSearch2JSON and type the following code:

public String mapSearch2JSON(String query)
	{
		String jsonString = "";
		query = query.trim().replace(' ', '+');
		String url = "http://maps.google.com/maps?f=q&source=s_q&output=json&start=0&q="+query;
		try {
			URL urlObject = new URL(url);
			URLConnection urlConn = urlObject.openConnection();

			BufferedReader in = new BufferedReader( new InputStreamReader(urlConn.getInputStream()));

			String inputLine;
			while ((inputLine = in.readLine()) != null){
				jsonString = jsonString + inputLine;
	        }
	        	in.close();
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		jsonString = jsonString.replace("while(1);", "");
    	return jsonString;
	}

Basically, what I’m doing here is to trim the input string and change the white space and use the ‘+’ character instead (you should know why). Then, the request is sent and the response is stored in the jsonString variable. And, before returning this value, the while(1); string is removed.

1.4) The next thing to do is to parse the JSON string. But before doing it, add a new class called Marker which will store the marker’s information. The code should look like this:


public class Marker {
	private String Name;
	private String Address;
	private double Latitude;
	private double Longitude;
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	public String getAddress() {
		return Address;
	}
	public void setAddress(String address) {
		Address = address;
	}
	public double getLatitude() {
		return Latitude;
	}
	public void setLatitude(double latitude) {
		Latitude = latitude;
	}
	public double getLongitude() {
		return Longitude;
	}
	public void setLongitude(double longitude) {
		Longitude = longitude;
	}

}

I have only covered the values for name, address, latitude and longitude. But you can update this Class according to your needs.

1.5) Go back to the JsonConverter Class and add the below public method:

public ArrayList jsonParser(String json)
	{
		ArrayList markersList = new ArrayList();
		try
		{
			JSONObject jsonObject = (JSONObject)JSONSerializer.toJSON(json);
			JSONObject overlays = jsonObject.getJSONObject("overlays");

			if(!overlays.containsKey("markers"))
				return markersList;

			JSONArray markers = overlays.getJSONArray("markers");

			String name = "";
			String address = "";
			JSONObject marker;
			double latitude;
			double longitude;

			for(int i = 0; i < markers.size(); i++)
			{
				// gets marker object
				Marker markerObj = new Marker();
				marker = markers.getJSONObject(i);

				//gets address value
				address = marker.getString("laddr");

				//gets name value (if it is not empty)
				if(marker.containsKey("name"))
					name = marker.getString("name");

				//gets lat & lon
				JSONObject latlon = marker.getJSONObject("latlng");
				latitude = latlon.getDouble("lat");
				longitude = latlon.getDouble("lng");

				//save all values into Marker object
				markerObj.setName(name);
				markerObj.setAddress(address);
				markerObj.setLatitude(latitude);
				markerObj.setLongitude(longitude);

				//add the object to the list
				markersList.add(markerObj);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return markersList;
	}

The code will convert the JSON string into a JSON object. Then, it will look for the overlays and markers tag. Each time a marker is found, a Marker object will be created and added into the ArrayList. At the end, a collection of Markers will be returned.

1.6) If you want to test the code, run the below Main class. It will submit a request and print the name for all the returned markers.

public class Main {

	public static void main(String[] args) {
		JsonConverter converter = new JsonConverter();
		String jsonString = converter.mapSearch2JSON("gas station near 1065 La Avenida Street, Mountain View, CA");

		ArrayList markers = converter.jsonParser(jsonString);
		for(Marker marker : markers)
		{
			System.out.println(marker.getName() + " -> " + marker.getAddress());
		}
	}
}

image

And that’s all! now you can format the search results at your convenience. Keep in mind that the response only covers the first 10 records of your search result, Google maps shows 10 results per page. You can use the same code described in here to fetch ALL the results, but I won’t go through the solution.

About these ads

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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: