Two years back I had to write a new mapping implementation for my former employer, who wanted to move away from MapQuest. We chose Google Maps, for a number of reasons. I wrote the implementation using Scott Mebberson's implementation, the Google Maps Tag. I was quick and easy, and ultimately we had to ditch it at the last minute. Why? Google's licensing at the time was too restrictive for our use case. Running almost 2,000 sites of of one codebase, we would have had to get a separate license key for each site, or get an enterprise license through Google. We were going down that path originally, but the cost at the time was almost $40k, and required some work on their part that they couldn't make our deadline (during the holidays), so when the autorenewal kicked in on (cheaper) MapQuest we just rolled with it.
Last month my former employer once again wanted to get rid of MapQuest. First we looked at our implementation, realizing that the same hurdles were in place. Next we looked at ColdFusion 9's new cfmap tags. That implementation works the same way, requiring the API key per domain. Luckily, I remembered seeing a tweet from someone about changes to Google's Maps API. A change that wouldn't require an API key anymore. So, I went to check it out.
The latest version of the Google Maps Javascript API is very nice, and has one very significant change.
The JavaScript Maps API V3 is a free service, available for any web site that is free to consumers.
This was perfect, as all of our sites were free to consumers. The first thing I did was try to make some adjustments to my initial implementation from Scott's tags. This didn't work, as there were some major differences in Google's new implementation. I ended up rewriting the entire implementation to work with the new API, creating my own custom tag. In forking Scott's code, I had to keep the license the same, which allows me to put it back out to the community at large (and with the approval of my old boss).
CFGMap is now available on RIAForge for download. My simple example source code is included with the download, and all code is heavily documented. My example uses JQuery for the basic DOM manipulation involved, but JQuery is not required to use the tag itself. You'll want to pay special attention to the testmap.js file, which shows how you can access your map object to plot directions and stuff. The tag puts a map on the page, and plots the points you've fed to it. It will even trigger a callback method, that you define, for passing lat/lng info that's been goelocated back to your database, reducing the geolocation hits on subsequent map visits.
It's only the first go-around with the updated library, and I'm sure that changes will need to be made at some point. I welcome any and all feedback, questions, and suggestions.


#1 by JD on 1/19/11 - 7:52 AM
#2 by Steve 'Cutter' Blades on 1/19/11 - 8:11 AM
Thanks for the heads up. I've corrected the link.
#3 by Srinivas on 2/16/11 - 5:35 AM
I am getting JS syntax error on line no. 56 in testmap.js.You can observe in your demo link also http://examples.cutterscrossing.com/CFGMap/index.c....
Kindly let me know the fix.
FYI, CFMX 6 doesn't support "cfloop array" also structNew format "{}"
Seems to be every thing fine on lower versions of CF.
Thanks in advance
#4 by Steve 'Cutter' Blades on 2/16/11 - 7:10 AM
#5 by ja on 3/22/11 - 3:30 PM
Got Rays to work fine for a single address, but unable to make it work for multiples..
Just tried out your sample, getting the following error:
--------------------------------
Invalid CFML construct found on line 130 at column 24.
ColdFusion was looking at the following text:
{
The CFML compiler was processing:
a script statement beginning with "REQUEST.attr" on line 130, column 9.
a cfscript tag beginning on line 129, column 2.
The error occurred in C:\Inetpub\wwwroot\PMM\index.cfm: line 130
128 :
129 : <cfscript>
130 : REQUEST.attr = {};
131 : REQUEST.attr.width = "85%"; // The width of the map
132 : REQUEST.attr.height = "500px"; // The height of the map
---------------------------------
I have all of your content posted into a site subfolder called \gmaps,
using Coldfusion 7.02 and MySQL backend..
On another note, if using the UDF function queryRowToStruct(query)
- What changes need to be made in your code to "append to the locArr"..?
- I already have my Recordset query called "rsMapMultiple" created
Thanks, ja
#6 by Steve 'Cutter' Blades on 3/22/11 - 8:47 PM
#7 by ja on 3/23/11 - 10:01 AM
-------------------------------------------
Could not import the tag library specified by "/CustomTags".
The following error was encountered: C:\Inetpub\wwwroot\CustomTags. Please ensure that you have specified a valid tag library.
The CFML compiler was processing:
a cfimport tag beginning on line 147, column 2.
The error occurred in C:\Inetpub\wwwroot\COE\gmaps\index.cfm: line 147
146 : <!--- Call for the Custom Tag --->
147 : <cfimport taglib="/gmaps/customtags" prefix="ui">
148 : <ui:cfgmap attributeCollection="#REQUEST.attr#" />
---------------------------------------------
I went ahead & copied the cfgmap.cfm to the site root, and changed the index.cfm Line 147 to <cfimport taglib="/" prefix="ui">
and now get the error:
---------------------------------------------
Attribute validation error for tag CFLOOP.
The tag does not allow the attribute(s) ARRAY. The valid attribute(s) are COLLECTION,CONDITION,DELIMITERS,ENDROW,FROM,INDEX,ITEM,LIST,QUERY,STARTROW,STEP,TO.
The error occurred in C:\Inetpub\wwwroot\PMM\index.cfm: line 113
111 : <cfif ArrayLen(REQUEST.locArr) gt 1><!--- For sites with more than one mapped location --->
112 : <select id="locID" name="locID">
113 : <cfloop array="#REQUEST.locArr#" index="REQUEST.i">
114 : <option value="#REQUEST.i.locationID#">#REQUEST.i.name#</option>
115 : </cfloop>
-----------------------------------------------------
Do you think theres too many CF9 differences to work with my CFMX7.02..?
Thanks again,
ja
#8 by ja on 3/23/11 - 10:08 AM
- I tried the code on two sites,(COE & PMM), but will only use the PMM one from now on..
#9 by ja on 3/25/11 - 6:08 PM
Here is where I'm at now:
1) I ended up changing the cfloop from:
--------------------------------
<cfloop array="#REQUEST.locArr#" index="REQUEST.i">
<option value="#REQUEST.i.locationID#">#REQUEST.i.name#</option>
</cfloop>
to the following:
--------------------------------
<cfloop
index="intNodeIndex"
from="1"
to="#ArrayLen( REQUEST.locArr )#"
step="1">
<cfset REQUEST.i = REQUEST.locArr[ intNodeIndex ] />
<option value="#REQUEST.i.locationID#">#REQUEST.i.name#</option>
</cfloop>
-------------------------------
Then it started stopping on the cfloop array in cfgmap.cfm..
I tried to update this cfloop array to make it compatible to CF7.02. Gladly I get no errors, but no google Map either?
Here is what that code is currently, after my hacking..
---------------------------------
<cfloop
index="intNodeIndex"
from="1"
to="#ArrayLen( ATTRIBUTES.locArray )#"
step="1">
<cfset VARIABLES.i = ATTRIBUTES.locArray[ intNodeIndex ] />
<cfoutput>#ATTRIBUTES.locArrayName#.push(new CFGMapLocation({
locId: #VARIABLES.i['locationID']#,
dispName: "#VARIABLES.i['Name']#",
addr1: "#VARIABLES.i['Address1']#",
addr2: "#VARIABLES.i['Address2']#",
city: "#VARIABLES.i['City']#",
state: "#VARIABLES.i['State']#",
zip: "#VARIABLES.i['zip']#",
lat: "#VARIABLES.i['Latitude']#",
lng: "#VARIABLES.i['Longitude']#",
primary: #VARIABLES.i['primaryMarker']#,
phone: "#VARIABLES.i['phone']#"
}));</cfoutput>
<cfif VARIABLES.i['primaryMarker'] and (Len(VARIABLES.i['Latitude']) and Len(VARIABLES.i['Latitude']))>
<cfset VARIABLES.LatLng = VARIABLES.i['Latitude'] & "," & VARIABLES.i['Longitude'] />
</cfif>
</cfloop>
------------------------------------
Thus far, as mentioned earlier, CF7 to CF8 involves updating Structs & cfloop arrays, anything else..?
Hey Srinivas, do you have the updated changes that are CF7 compatible..?
Thanks,
jaa
#10 by Steve 'Cutter' Blades on 3/26/11 - 7:33 AM
Glad you're making headway. I'd say your next step is to open your page in Firefox with Firebug installed and start checking the Console and Net tabs. The net tab will show you if the accompanying script file is loading properly, and the Console tab will tell you if any javascript errors are occurring.
#11 by ImageGuru on 5/13/11 - 7:43 AM
Once I fixed that, presto! Thanks a bunch to Steve and Scott (and anyone else who worked on this). It saved me a huge amount of work.
-Kevin
#12 by Steve 'Cutter' Blades on 5/13/11 - 11:44 AM
Glad this helped you out! The documentation in the tag should have mentioned the resource pathing. I'll go back and double check it. If you have any suggestions down the line, or want to contribute, ping me through the contact link at the bottom of the page.
#13 by ja on 5/13/11 - 12:32 PM
Thanks for the updated post on this..
Sadly, I'm still not getting anywhere..
Would you mind posting a link to your index.cfm for download so I can compare with mine?
What is your site structure/layout.. I kept the same structure as the original example:
-Site Root
---gmaps
----------cfc
----------css
----------customtags
----------images
----------scripts
----------index.cfm
Thanks, ja
#14 by Jeffrey Lemire on 12/18/11 - 5:39 PM
Thanks again for this script!
#15 by Cutter on 12/19/11 - 5:50 PM
I'm hoping to get this one up on GitHub soon too. Just been kinda swamped.