OpenLayers Map with Tooltips
OpenLayers Demo with Multiple Layers of Data
Same OpenLayers Demo with Custom Tooltips
There has been a lot of development into JavaScript mapping libraries and after playing around with D3 and Raphael, I wanted to try something more map specific. I briefly looked into Google Maps, Leaflet, ESRI, Cloudmate, Polymaps, ModestMaps and many others but I decided on OpenLayers. After reading several good threads on comparing client side map libraries I felt that OpenLayers got the highest overall vote. The OpenLayers API documentation also seems very promising. So, today, I am going to find some interesting geographical data, extract and convert it into a good geo format, and use OpenLayers to visualize the data on the map.
Retrieving Data from Wikipedia
Here are the 7 IUCN protected area categories that I will be plot on the OpenLayers map:
- Category Ia — Strict Nature Reserve
- Category Ib — Wilderness Area
- Category II — National Park
- Category III — Natural Monument or Feature
- Category IV — Habitat/Species Management Area
- Category V — Protected Landscape/Seascape
- Category VI – Protected Area with sustainable use of natural resources
Since I am only interested in the title and geo-coordinates of these locations, this is exactly what I need. I was not familiar with KML format so I tried the geoRSS link but it took me to a Bing error page. There are 1,912 National Parks on the list so performing this conversion seems to kill Bing servers every time. The KML link takes you to a kmlexport script which is more powerful and worked very well. OpenLayers has excellent support for KML but if you are use to JSON, the ogr2ogr web client is an excellent online converter to geoJSON.
Mapping locations into OpenLayers World Map
Since I have extracted all the categories of protected areas, I wanted to display them using different layers representing each category. I created a function that draws the map with a base layer and then I created a function that adds any layer to the map based on a KML resource that you can pass and a name for that layer. I didn’t want to load all the layers on initialization (I wanted to uncheck some layers when the map is loaded) so I used the setVisibility function to turn them off before adding to the map.
So, each layer shows different categories of landmarks on the map but all the points use the same orange circle. I glanced at the OpenLayers styling documentation and added a function and parameter to control the style for each KML resource. Next, I wanted to show the title in a tooltips for each point on the map. Bringing the data from KML resources to the page is simple (look at extractAttributes: true
and title:'${name}'
in the source of the demos) but I was surprised that there are no good examples or documentation around making tooltips.
The following jsFiddle example, helped me leverage the SelectFeature and AnchoredBubble constructors to make tooltips but I was not too happy with the way these tooltips looked (defined height and rounded corners). This was clearly meant to serve the purpose of a popup or modal not a mouse tooltip. Still, it’s a pretty good solution, check out the demo here.
Tooltips are a pretty simple concept so I wanted to code it up myself. I added a tooltip element inside the map element and gave it some CSS. Then I created a tooltip function that grabs all the data points on the page, loops through them, and listens to mouseover and mouseout events. On these events I grab the position of each data point, the title of the data point, and insert this information into the tooltip element. I did some research around events and callbacks in openlayers and registered a callback that executes the tooltip function after every layer has been loaded. Since you can pan and zoom the map, I also had to register those callbacks and make sure that we re-execute the tooltip function when the user interacts with the map. Here is the demo of my custom tooltip solution for openlayers.
Related
SVG Tooltips
Top Data Formats for Geographical Points
OpenLayers Example with Yeoman, Sinatra, and mongoDB