How to make a map based on OpenStreetMap
I recently made an OpenStreetMap (OSM) based AJAX map of all the Hackerspaces in OSM. It pulls out the list of hackerspaces from XAPI, converts it from OSM to GeoRSS using XSLT, then displayes it on a map using OpenLayers.
The XAPI URL I'm using is:
wget -q -O /var/www/osm-hackerspaces/hackerspaces.osm
"http://osmxapi.hypercube.telascience.org/api/0.6/*[leisure=hackerspace]"
I'm also setting a nice User-Agent giving my contact details and I've installed a local squid proxy and using that. I'm being a good web citizen
I convert the OSM file to GeoRSS using the following XSLT file:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/osm"> <?xml-stylesheet href="http://yelp.com/css/atom.css" type="text/css" media="screen"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"> <rights></rights> <title>Hackerspaces in OpenStreetMap</title> <link href="http://www.technomancy.org/osm-hackerspaces/" /> <updated> <xsl:for-each select="./node"> <xsl:sort select="@timestamp" data-type="text" order="descending" /> <xsl:if test="position() = 1"> <xsl:value-of select="@timestamp" /> </xsl:if> </xsl:for-each> </updated> <author> <name>OpenStreetMap contributors</name> </author> <xsl:for-each select="./node"> <entry> <title><xsl:value-of select="./tag[@k='name']/@v" /></title> <xsl:choose> <xsl:when test="not(./tag[@k='website']/@v)"> <link rel="alternate" type="text/html" href="" /> <id></id> </xsl:when> <xsl:when test="substring(./tag[@k='website']/@v, 0, 5) = 'http'"> <xsl:variable name="website" select="./tag[@k='website']/@v" /> <link rel="alternate" type="text/html" href="{$website}" /> <id><xsl:value-of select="$website" /></id> </xsl:when> <xsl:otherwise> <xsl:variable name="website">http://<xsl:value-of select="./tag[@k='website']/@v" /></xsl:variable> <link rel="alternate" type="text/html" href="{$website}" /> <id><xsl:value-of select="$website" /></id> </xsl:otherwise> </xsl:choose> <updated><xsl:value-of select="./@timestamp" /></updated> <summary type="html"><xsl:value-of select="./tag[@k='addr:full']/@v" /><xsl:text> </xsl:text><xsl:value-of select="./tag[@k='note']/@v" /></summary> <geo:long><xsl:value-of select="./@lon" /></geo:long> <geo:lat><xsl:value-of select="./@lat" /></geo:lat> </entry> </xsl:for-each> </feed> </xsl:template> </xsl:stylesheet>
I use xmlstarlet to convert using this command line:
xmlstarlet tr osm2georss.xslt hackerspaces.osm > hackerspaces.georss.xml
I made a little 20x20 logo from the hackerspace logo.
OpenLayers has built in support for GeoRSS, so it was just a matter of giving it the filename of the above.
I have a cron running that every 6 hours to update it.