Google announced the Places API recently at Google I/O (2011) and I was looking into this, to see how this API can be used in conjunction with ColdFusion maps created with CFMAP. The Places API can be used to retrieve place information which includes:
Place Search Requests - retrieving the places of interests near a user's location:
https://maps.googleapis.com/maps/api/place/search/output?parameters
Here the user has an option of specifying the output format as either json or xml and is required to pass a few parameters:
For the purpose of this example, I have specified the latitude and longitude values for 'Sydney, Australia' (I've lived here!!) and have specified the type of business as doctor and book_store. The radius is specified as 2000 meters (2 Kms) and the sensor is set to false. The output format is specified as json.
The json response would contain three root elements: status, results and html_attributions. If there were no errors in performing the request operation and the response contained at least one result then the response status is set to "OK". The result element is an array of places sent in response to a request, this would include the place name, its geometry (latitude and longitude information), place id, reference, icon, types, vicinity.
The results array in the response can then be used to add places to the ColdFusion's map. However, on a Google Map when a user clicks on a location a popup is shown which includes the Address and the Phone number of the selected location. To get more details on a particular location, another request should be made to retrieve the place details such as address, phone number, rating.
Place Detail requests - retrieve place details:
Similar to the previous one, the HTTP request to retrieve the place details is:
https://maps.googleapis.com/maps/api/place/details/output?parameters
As mentioned earlier, output can be either json or xml. The reference value obtained from the previous HTTP call (Place Search request) is then passed as a parameter to retrieve the place details. Other required parameters include the sensor and the key. The cfhttp request to get the details is of the form:
As seen in the above code, the arrayResults containing the results of the place search request is iterated in the cfloop tag. The reference value in the arrayResults is then used in each iteration to get the place details. The place details are then used populate the windowContent array, which contains the html markup to show when the user clicks on any of the map item.
The CFMAP and CFMAPITEM tag can then be used to render a Google map and add places of interests to the map:
The CFMAPITEM tag is used to add places of interests on the map using the latitude and longitude information obtained from the place search request. The markerwindowcontent attribute would contain the address and the phone number information obtained from place detail request. The map rendered would look similar to the one shown below:
- Places of interests such as parks, restaurants, hospitals which are nearby to the users location.
- More detailed information on the place, such as the address, phone number etc,.
The API can also be used to perform check-in at a particular place and to add\delete a place. These check-ins can then be used to evaluate the popularity of the place. In this post I'll explain how to retrieve the places of interests and displaying the same on a ColdFusion map using CFMAP.
Place Search Requests - retrieving the places of interests near a user's location:
You can send a HTTP request to the URL of the form:
https://maps.googleapis.com/maps/api/place/search/output?parameters
Here the user has an option of specifying the output format as either json or xml and is required to pass a few parameters:
- key (required): The application's API key. The Places API uses this information to identify your application.
- location (required): This will be the latitude and longitude information of a particular place around which the places of interests are to be found.
- radius (required): to specify the radius within which the places of interests are to be found. The value specified will be considered in meters.
- sensor (required): to indicate whether the place request is from a device using the location sensor. It can be either true or false.
- types (optional): the user might be interested in various types of businesses such as library, park, gym etc,. You can also specify multiple types which are separated by a '|' (type1|type2|type3).
- name (optional): A term to be matched against the names of places. This will restrict the results to contain only those with the specified name.
- language (optional): The language code to indicate the language in which the results are to be returned.
With the above information, you can issue a HTTP request using ColdFusion's cfhttp tag:
<cfhttp url="https://maps.googleapis.com/maps/api/place/search/json"
method="get"
result="gmapData">
<cfhttpparam type="url"
name="location"
value="-33.8670522,151.1957362">
<cfhttpparam type="url"
name="types"
value="doctor|book_store">
<cfhttpparam type="url"
name="radius"
value="2000">
<cfhttpparam type="url"
name="sensor"
value="false">
<cfhttpparam type="url"
name="key"
value="{API_Key}">
</cfhttp>
For the purpose of this example, I have specified the latitude and longitude values for 'Sydney, Australia' (I've lived here!!) and have specified the type of business as doctor and book_store. The radius is specified as 2000 meters (2 Kms) and the sensor is set to false. The output format is specified as json.
The json response would contain three root elements: status, results and html_attributions. If there were no errors in performing the request operation and the response contained at least one result then the response status is set to "OK". The result element is an array of places sent in response to a request, this would include the place name, its geometry (latitude and longitude information), place id, reference, icon, types, vicinity.
The results array in the response can then be used to add places to the ColdFusion's map. However, on a Google Map when a user clicks on a location a popup is shown which includes the Address and the Phone number of the selected location. To get more details on a particular location, another request should be made to retrieve the place details such as address, phone number, rating.
Place Detail requests - retrieve place details:
Similar to the previous one, the HTTP request to retrieve the place details is:
https://maps.googleapis.com/maps/api/place/details/output?parameters
As mentioned earlier, output can be either json or xml. The reference value obtained from the previous HTTP call (Place Search request) is then passed as a parameter to retrieve the place details. Other required parameters include the sensor and the key. The cfhttp request to get the details is of the form:
<cfloop array="#arrayResults#"
index="placesObject">
<cfhttp url="https://maps.googleapis.com/maps/api/place/details/json"
method="get"
result="placeDetails">
<cfhttpparam type="url"
name="reference"
value="#placesObject.reference#">
<cfhttpparam type="url"
name="sensor"
value="false">
<cfhttpparam type="url"
name="key"
value="{API_Key}">
</cfhttp>
<cfset placeDetails = #deserializeJSON(placeDetails.fileContent).result#>
<cfset arrayAppend(windowContent,
"<h3>" & placeDetails.name & "</h3><br><h5>" & placeDetails.formatted_address &
"<br>Phone: " & placeDetails.formatted_phone_number & "</h5>")/>
</cfloop>
As seen in the above code, the arrayResults containing the results of the place search request is iterated in the cfloop tag. The reference value in the arrayResults is then used in each iteration to get the place details. The place details are then used populate the windowContent array, which contains the html markup to show when the user clicks on any of the map item.
The CFMAP and CFMAPITEM tag can then be used to render a Google map and add places of interests to the map:
<cfmap name="myMap"
centerlatitude="-33.8670522"
centerlongitude="151.1957362"
tip="Sydney"
width="800"
height="700"
zoomlevel="16">
<cfloop array="#arrayResults#"
index="mapObject">
<cfmapitem name="#mapObject.name#"
latitude="#mapObject.geometry.location.lat#"
longitude="#mapObject.geometry.location.lng#"
tip="#mapObject.name#"
markerwindowcontent="#windowContent[count++]#"
markericon="#mapObject.icon#">
</cfloop>
</cfmap>
The CFMAPITEM tag is used to add places of interests on the map using the latitude and longitude information obtained from the place search request. The markerwindowcontent attribute would contain the address and the phone number information obtained from place detail request. The map rendered would look similar to the one shown below:
I'm struggling with getting this to work. I have tried to use the exact code above (except substituting API_Key for my Google Maps API key) and I get an error - "Variable ARRAYRESULTS is undefined." Granted, I'm a novice at ColdFusion (and brand new to CFMAP), so I apologize in advance if this is a stupid rookie mistake...
ReplyDeleteJohn, the response that you receive from the HTTP request has to be de-serialized. Try putting before the cfloop tag. I think that would fix it. Let me know if it doesn't I'll send you the cfm file.
ReplyDeleteThanks so much, but now I get an error with this CFSET that says "Complex object types cannot be converted to simple values."
ReplyDeleteLet me know your email id, I'll send the cfm file to you. You can send me your email id through the 'Contact Me' page as well.
ReplyDelete