Google Mapping: Single Address

After several weeks of setup, now is the time to get down to brass tacks and build an embedded Google map in FileMaker. We'll be starting with a single address. My goal is to have this work with a set of address records and change as we flip between records. We're going to start at the very beginning, so get your computers out...



First, we need a new FileMaker file. Create something called 'map.fp7' and give it a single table called 'addresses' with a column/field called 'address' (make it a standard text field) and another field called 'source' (make it a global text field). You should be able to create some records in this table, typing the address in as a single line into the address field, something like this:

1 Infinite Loop, Cupertino, CA

You don't need the ZIP. Google will take care of that.  Go ahead, add a few more addresses.

Next, we need a layout with a Web Viewer on it. Here's where things slow down a bit...what should the Web Viewer calculation be?

Stepping back, we need to find some example code for the Google Maps API. They have an entire page on the subject (go ahead, take a look...I'll wait). I grabbed some sample code and made it the simplest I could (and still have it work):

<html style="height:99%">
  <head>
   <script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=INSERTKEYHERE" type="text/javascript"></script>
   <script type="text/javascript">
    function initialize() {
     if (GBrowserIsCompatible()) {
      map = new GMap2(document.getElementById("map_canvas"));
      geocoder = new GClientGeocoder();
      address = "
1 Infinite Loop, Cupertino, CA";
     }
     if (geocoder) {
      geocoder.getLatLng(
      address,
      function(point) {
      if (!point) {
       alert(address + " not found");
      } else {
       map.setCenter(point, 11);
       var marker = new GMarker(point);
       map.addOverlay(marker);
       marker.openInfoWindowHtml(address);
      }
     }
    );
   }
  }
</script>
</head>
  <body onload="initialize()" onunload="GUnload()" style="height:99%">
   <div id="map_canvas" style="width:99%; height:99%"></div>
  </body>
</html>

Let's take a look at that HTML more closely. First, the <head>:

<script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=INSERTKEYHERE" type="text/javascript"></script>

This script tag tells our page where to find the Google Maps API (which is JavaScript), as well as which version (2.x) and what key to use. Remember that API Key I had you get a couple weeks back? You can replace INSERTKEYHERE with your key.

Next is an actual local script (inside the <script> tag). It defines a function initialize() which is called when the page loads (onload="initialize()" in the <body> tag). This is the meat and potatoes of this script.

if (GBrowserIsCompatible()) {
  map = new GMap2(document.getElementById("map_canvas"));
  geocoder = new GClientGeocoder();
  address = "
1 Infinite Loop, Cupertino, CA";
}

First, check for browser compatibility. If it's compatible, create a new map object, geocoder object and address. Note that the map takes a parameter that defines the ID of the element it should be shown within (in this case map_canvas). This corresponds to the ID of our div element later on. The address is hard-coded in this example, but we'll change that later.

if (geocoder) {
  geocoder.getLatLng(
  address,
  function(point) {
  if (!point) {
   alert(address + " not found");
  } else {
   map.setCenter(point, 11);
   var marker = new GMarker(point);
   map.addOverlay(marker);
   marker.openInfoWindowHtml(address);
  }
}

Next, we'll geocode (which retrieves lat/lon information) and add the address to the map. If the geocoder exists (that is, if it was successfully created in the previous section), then use the getLatLng function of the geocoder object. The precise details of this section can be confusing to a novice. In any case, the function takes the address and a call-back function which gets the point (a lat/lon pair), which can be applied to the map. If the point exists (the address was found and geocoded), then the map is centered on that point and set to a zoom level of 11 (the higher the number, the closer the zoom, on a 0-20 scale). A new marker is created from that point, the marker is added to the map and the info window is set to address (the info window can be anything, but in this example we're keeping it simple).

Finally, the <body> is used to build the page.

<body onload="initialize()" onunload="GUnload()" style="height:99%">
  <div id="map_canvas" style="width:99%; height:99%"></div>
</body>

This loads the initialize() function when the page opens. It also defines a div with the correct ID as used in the new GMap2 code earlier. I've used style information to make sure the map takes up the entire width and height of the page.

If you copy this text out to a file and open it in a browser, it should work exactly like this online demo.

Finally, we just need to get this into a Web Viewer. Let's do that first, without worrying about which address we're mapping. Remember that 'source' field I had you make (a global text field)? Paste the HTML into that field. Then, make a Web Viewer with the following calculation (I've found it easier to reference fields that contain the HTML rather than try to type the HTML directly into the Web Viewer calculation):

"data:text/html," & map::source

Now, take a look at that in browse mode. It's right about now that about half of you are saying "Huh?" and the other half are saying "Wow!". Because this works on PC but not on Mac. Yes, I've taken half of you down a wild goose chase on purpose.

Here is a screenshot of the PC side:

And of the Mac side:

 

I've isolated why this doesn't work (it has something to do with the way FileMaker is showing the local HTML within the Web Viewer and the host assignment which causes the Google API Key to not be valid), but it's a bit hard to go into here.  Suffice it to say, if you're on Mac then you'll have to wait a while to get this to work.

For those lucky PC people (wow, that sounds funny to say), here's how they can get it working the way one would expect (flipping between records and viewing the location on the map instead of always seeing Cupertino).

First, change the address line in the JavaScript from this:

address = "1 Infinite Loop, Cupertino, CA";

To this:

address = "#ADDRESS";

I'm just using "#ADDRESS" as a placeholder for later substitution.  Use the following calculation in the Web Viewer:

"data:text/html," & Substitute ( map::source ; "#ADDRESS" ; map::address )

You can also download a sample file that includes everything I've done (you may have to right-click that link to save the file to your desktop). I'll pick up making this work cross-platform soon. With the holidays coming up, my next post might not be until January. Keep your eyes peeled and everybody have a happy and safe holiday!

Update: Why doesn't this work on a Mac?

Update: Cross Platform Solution

Simple method using the "output=embed" parameter

You can also use the "embedded map" URL format that Google provides to get single markers. This doesn't appear to work for multiple addresses. As an example, use the following URL for your web viewer in the sample file described above: "http://www.google.com/maps?q=" & Addresses::Address & "&ie=UTF8&t=h&z=12&output=embed" Note that the zoom=12 and the map type is hybrid ("t=h") in my example in this comment. Other types are possible. Read more about this at: http://mapki.com/wiki/Google_Map_Parameters

Routes?

Is there a way to incorporate this using Google Overlays? I have 2 points and I wish to draw a line between them using:

var polyOptions = {geodesic:true};
var polyline = new GPolyline([
new GLatLng(40.65642, -73.7883),
new GLatLng(61.1699849, -149.944496)
], "#ff0000", 10, 1, polyOptions);
map.addOverlay(polyline);

I've tried replacing the GLatLng with #ADDRESS2, then adding a Substitute into your code but I can't get it to work.

Any suggestions? Cheers

Nasty hacks

So far nasty hacks are based on a text file either just local or written in the web server locally. Nothing that clever.

Is this my old friend Damian

Is this my old friend Damian from the UK? Send me a note via our contact us page and I can write you personally.

As far as getting this to work on OSX, you have to use a different technique (which I plan to get to in the next week or so). Hold tight... Care to share any of your "nasty hacks"?

In any case, this isn't Google's problem. It's really FileMaker's. Rather than describe the problem in detail here, I'll post something to the blog proper. Watch for that, too. Cheers!

Pretty cool

You are right about the issue on OS X, I have tried loads of nasty hacks and its really driving me mad. Do you actually have an idea on how to make this work or is it a case of waiting for Google?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><p><div> <br><img>
  • Lines and paragraphs break automatically.

More information about formatting options

Verification
This question is for testing whether you are a human visitor and to prevent automated spam submissions.