Tuesday, December 08, 2009

Geocoder without Search button

We are used to see geocoders with address input field and [Search] button.

We can discard the button and use 'onchange' event of the input field instead.

It works quite well. Just type in the address and click anywhere on the page. Well not anywhere because click on map is preventDefaulted. Hitting [Enter] key works too. @M$: please don't file a patent application.

Text input field can also be used for showing how the geocoder actually understood the address.

Full example.

Monday, December 07, 2009

Sidebar with makeMarker() v3

Wouldn't that be convenient if makeMarker(options) would construct a sidebar entry as well. See it here.

A separate SidebarItem() constructor was written. It creates a button element and appends that to a div with id="sidebar" by default. makeMarker() calls the constructor if you have set an option property {sidebarItem: "My label"}

The basic button element needs some CSS cure. You can also style individual sidebar items by setting different CSS class names for them. {sidebarItemClassName: "important_item"}

The events are set to work bidirectionally.
  • click on sidebar -> click on marker
  • select on sidebar -> click on marker (select by [Tab])
  • click on marker -> focus on sidebar
  • mouseover on sidebar -> mouseover on marker
  • mouseout on sidebar -> mouseout on marker
One of the reasons why I selected a button element was that it is 'focusable' and 'selectable'. You can open an info window by stepping the focus to a sidebar item by [Tab] or [Shift]+[Tab] and select the item by [Enter] or [Space] (some browsers). That is called accessibility.

Also you can use :hover and :focus CSS pseudoselectors. (:focus does not work with IE)

SidebarItem() instance has methods addIn() and remove(). We need addIn() to decide where to add the item. That helps to implement the categories.

Thursday, November 26, 2009

v3 markers and info windows

v3 constructors like Marker(opts) and InfoWindow(opts) take an options object as their single parameter.

How about composing a createMarker(opts) function that also takes a single options object and creates both Marker and Infowindow.

Marker and InfoWindow options have 'position' and 'zIndex' properties in common. All the other property names are unique.

You have to give 'position' for a Marker. Giving the same position to InfoWindow has no effect if InfoWindow.open() is given an anchor.

There is no need to set zIndex of InfoWindow if you are using just a single instance of InfoWindow. It even doesn't have any visible effect. So we can freely use zIndex to control the marker.

There was no need to convert any property names. makeMarker(opts) function can be seen in action here.

The single options object can further be extended to include new properties like 'category' and 'sidebarLabel'.

Wednesday, October 14, 2009

Custom tooltip for v3

v3 BoundsBox library provides constructors to create a rectangular overlay by LatLngBounds or by LatLng plus km-dimension (also miles or nautic miles). You can also overlay images that scale with zoom.

It is still missing an overlay with pixel dimensions. For tooltips and other labeling. It is coming.

I haven't included the 'tiptool' to BoundsBox library yet. There are a few things still under development.

I am impressed with 'universional' concept of a library that Paul Kulchenko has implemented. He has written some impressive Canvas experiments that work with v2 and v3 with one and only script.

That is the way that Google Maps API libraries should be written.

Thursday, September 24, 2009

Gecoder response structure

I made simple test pages for version 2 and version 3 that display the geocoder response object contents prettyprinted.

First I was using toSource() method of Firefox which is a handy way to have a look inside objects. You could say that is opposite to eval().

Using non-standard toSource() debugging method means that the pages would work only with FF. I think that all the browsers have a similar method internally, but it is exposed only in Gecko browsers.

I switched to JSON.stringify(). That is also built in FF3.1+ and even in IE but only in IE8 mode. The function is made cross-browser by loading Douglas Crockfords json2.js script. You can get it from json.org.

The line breaks, spaces and indents are generated by beautify.js from jsbeautifier.org

Monday, September 14, 2009

Zoom events

The following concerns version 2 of API.

There is a single zoomend(old, new) event in documentation. However there are a few additional undocumented events that return a lot of data about zoom action.

'zoomto' is triggered always when user changes zoom setting. It returns two parameters. The first one is a string that indicates how the zoom was started. The second is an object {infoWindow: boolean} that tells if the info window is open. Following string values are discovered:

- "zi" or "zo" When zoom button is clicked
- "zs_drag_zi " or "zs_drag_zo" When zoom slider is moved
- "zb_click_zi" or "zb_click_zo" When zoom bar is clicked
- "wl_zi" or "wl_zo" By scrollwheel zoom
- "key_zi" or "key_zo" When zoomed by keyboard +/-

If we have continuousZoom enabled, we get more events: 'zoomstart' and 'zooming'.

'zooming' is triggered repeatedly while animated zoom is under progress. The interval is a few tens of milliseconds.

'zoomstart' is triggered when continuous zoom is started by dblclick or scrollwheel. Its first parameter is -1 or 1 indicating the direction of the started zoom. The second parameter is a GLatLng mouse pointer position. By double rightclick zoomout the second parameter is a blank object.

I have discovered a third parameter, a boolean that is true only by dblclick-zoom-in?

When triggering a continuous zoom, we get a series of events:
  • zoomstart
  • zoomto
  • zooming
  • zooming
  • zooming
  • zoomend
And a lot of data with them.

Friday, August 28, 2009

Accessibility and Google Maps

My understanding about accessibility of a web page is, that all its contents must be accessible without a mouse.

So was the Map Kitchen examples written. Take categories example and you can open any info window by [Tab] key, check the checkboxes by [space]. ([Shift[Tab]] to go back).

Accessibility is in the hands of the developer who writes the code for a map page. It is not built in Google Maps.

Patrick H. Lauke from Opera does not accept my opinion. We had a short public discussion on the forum and our opinions are:

Google Maps control elements (zoom, nav-buttons...) should be keyboard accessible

My opinion:
Those functions are easily made keyboard accessible by the page developer but they are not important. The contents must be accessible. There should be a method to open any info window without mouse.

Patric has made great work with a script that converts Google Maps control buttons keyboard accessible

Usability and Google Maps

What does usability and Google Maps have in common. At least one thing, they are synonyms.

Map is the user interface for any data - any. That is the reason why a search engine company acquired a startup that had the keys for that user interface.

We who write map pages, must keep in mind, that we are using map as the user interface because it is the most intuitive way to present any data. Our client or boss may see map as a decoration on the web page. Try to make them see the difference between a list of addresses or that list presented on a map.

I was very delighted to see that a blog called "In usability we trust" talks a lot about Google Maps. The blog is kept by a Swedish guy called Gabriel Svennerberg. He has written some high quality articles about Google Maps API.

Tuesday, August 11, 2009

Images on v3 map

BoundsBox extension was used for drawing rectangles on map a few posts ago.

The new version of BoundsBox (1.0) has option to insert images inside (visible or invisible) rectangles. The image is attached in a draggable pane of map. So it pans with map. It scales when map is zoomed. It is attached below markers, so it doesn't eat marker clicks. The behavior is equal to GGroundOverlay of v2 api.

A few more options and methods were introduced with the new version. They mainly serve image handling like opacity and z-index. Events 'imageloaded' and 'imageloaderror' are also provided.

See an example with a table of options and methods.

Update v1.1

The most latest version provides also an alternative constructor KmBox(). Instead of LatLngBounds it takes LatLng and kmX, kmY dimensions as its parameters. As a side product we got LatLng.destinationLatLng(bearing, distance) method. That calculates LatLng 'that many kilometers from this LatLng to that compass bearing'.

Curing IE8 complications

Many map pages work fine with all the other browsers but not IE8. Clicks seem to take place far away from the point that user actually clicked.

The bug has been archived in IE8 issue list since beta times. The only known workaround is to force IE8 to "IE7 combatibility mode".

Investigating Microsofts own code reveals that even they have not found any other workaround. You can find in the head section of Bing maps:

<meta http-equiv="X-UA-Compatible" content="IE=7" />

And in maps.google.com:

<meta http-equiv=X-UA-Compatible content=IE=EmulateIE7 />

Those tags make IE8 behave more like IE7 and cure the click coordinate issue. If someone is really interested what they actually do, I would recommend starting from this excellent study. What I learned about that article, is that the tag will not pass HTML5 validation.

Wednesday, July 22, 2009

Custom marker generators

There are some fancy free services that generate custom marker icons for us. Google Chart API provides many useful labeled map pin types. Even tilted ones.

Graham has released a fascinating service that generates all the needed files from an image file of your own. You upload the image as png, gif or jpeg and instantly you can download a zipped package containing:
  • 24-bit png icon image
  • shadow
  • printImage
  • mozPrintImage
  • printShadow
  • transparent
  • imageMap array

Monday, July 20, 2009

Drawing rectangles with V3

The experimental API v3 does not support polylines yet. We don't need polyline support for drawing simple rectangles. We can make browser to draw them.

BoundsBox for v3 is an extension that takes LatLngBounds object as an argument and draws the bounds on map. A DIV is created and made an OverlayView overlay object.

Styling of the rectangle is made with CSS. You can put text content also and even a background image. 'click' event is available, 'mouseover' is easily attached.

See the example that visualizes bounds that v3 geocoder returns.

Monday, July 13, 2009

Location by browser

Now we have two browsers that provide client location by JavaScript API, Firefox 3.5 and Google Chrome.

FF3.5 supports W3C specification (draft) and provides navigator.geolocation object. The objects getCurrentPosition() method returns coordinates and even heading and speed properties.

Chrome provides geolocation object by built in Google Gears.

Actually other browsers return the location too with Google Gears installed.

Test and read more from the links of this page. The page is the first one that I set sensor=true.