<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: maps</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/maps.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2024-09-28T21:41:15+00:00</updated><author><name>Simon Willison</name></author><entry><title>OpenFreeMap</title><link href="https://simonwillison.net/2024/Sep/28/openfreemap/#atom-tag" rel="alternate"/><published>2024-09-28T21:41:15+00:00</published><updated>2024-09-28T21:41:15+00:00</updated><id>https://simonwillison.net/2024/Sep/28/openfreemap/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://openfreemap.org/"&gt;OpenFreeMap&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
New free map tile hosting service from Zsolt Ero:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OpenFreeMap lets you display custom maps on your website and apps for free. […] Using our &lt;strong&gt;public instance&lt;/strong&gt; is completely free: there are no limits on the number of map views or requests. There’s no registration, no user database, no API keys, and no cookies. We aim to cover the running costs of our public instance through donations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The site serves static vector tiles that work with &lt;a href="https://maplibre.org/maplibre-gl-js/docs/"&gt;MapLibre GL&lt;/a&gt;. It deliberately doesn’t offer any other services such as search or routing.&lt;/p&gt;
&lt;p&gt;From &lt;a href="https://github.com/hyperknot/openfreemap"&gt;the project README&lt;/a&gt; looks like it’s hosted on two Hetzner machines. I don’t think the public server is behind a CDN.&lt;/p&gt;
&lt;p&gt;Part of the trick to serving the tiles efficiently is the way it takes advantage of &lt;a href="https://en.m.wikipedia.org/wiki/Btrfs"&gt;Btrfs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Production-quality hosting of 300 million tiny files is hard. The average file size is just 450 byte. Dozens of tile servers have been written to tackle this problem, but they all have their limitations.&lt;/p&gt;
&lt;p&gt;The original idea of this project is to avoid using tile servers altogether. Instead, the tiles are directly served from Btrfs partition images + hard links using an optimised nginx config.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;a href="https://github.com/hyperknot/openfreemap/blob/main/docs/self_hosting.md"&gt;self-hosting guide&lt;/a&gt; describes the scripts that are provided for downloading their pre-built tiles (needing a fresh Ubuntu server with 300GB of SSD and 4GB of RAM) or building the tiles yourself using &lt;a href="https://github.com/onthegomap/planetiler"&gt;Planetiler&lt;/a&gt; (needs 500GB of disk and 64GB of RAM).&lt;/p&gt;
&lt;p&gt;Getting started is delightfully straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const map = new maplibregl.Map({
  style: 'https://tiles.openfreemap.org/styles/liberty',
  center: [13.388, 52.517],
  zoom: 9.5,
  container: 'map',
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I &lt;a href="https://gist.github.com/simonw/da2b20711b96f745873ccb44a3347ce9"&gt;got Claude to help&lt;/a&gt; build &lt;a href="http://tools.simonwillison.net/openfreemap-demo"&gt;this demo&lt;/a&gt; showing a thousand random markers dotted around San Francisco. The 3D tiles even include building shapes!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Map of San Francisco in 3D with building shapes and small blue random markers dotted around." src="https://static.simonwillison.net/static/2024/openfreemap.jpeg" /&gt;&lt;/p&gt;
&lt;p&gt;Zsolt built OpenFreeMap based on his experience running &lt;a href="https://maphub.net"&gt;MapHub&lt;/a&gt; over the last 9 years. Here’s &lt;a href="https://blog.opencagedata.com/post/interview-zsolt-ero-maphub"&gt;a 2018 interview about that project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s pretty incredible that the OpenStreetMap and open geospatial stack has evolved to the point now where it’s economically feasible for an individual to offer a service like this. I hope this turns out to be sustainable. Hetzner charge &lt;a href="https://docs.hetzner.com/robot/general/traffic/"&gt;just €1 per TB&lt;/a&gt; for bandwidth (S3 can cost $90/TB) which should help a lot.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://cosocial.ca/@timbray/113216132761896850"&gt;Tim Bray&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;&lt;/p&gt;



</summary><category term="geospatial"/><category term="maps"/><category term="openstreetmap"/><category term="ai-assisted-programming"/></entry><entry><title>The many lives of Null Island</title><link href="https://simonwillison.net/2024/Jul/28/the-many-lives-of-null-island/#atom-tag" rel="alternate"/><published>2024-07-28T17:44:54+00:00</published><updated>2024-07-28T17:44:54+00:00</updated><id>https://simonwillison.net/2024/Jul/28/the-many-lives-of-null-island/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://stamen.com/the-many-lives-of-null-island/"&gt;The many lives of Null Island&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Stamen's custom basemaps have long harbored an Easter egg: zoom all the way in on 0, 0 to see the outline of the mystical "null island", the place where GIS glitches and data bugs accumulate, in the Gulf of Guinea south of Ghana.&lt;/p&gt;
&lt;p&gt;Stamen's Alan McConchie provides a detailed history of the Easter egg - first introduced by Mike Migurski in 2010 - along with a definitive guide to the GIS jokes and traditions that surround it.&lt;/p&gt;
&lt;p&gt;Here's &lt;a href="https://maps.stamen.com/toner/#19/0/0"&gt;Null Island on Stamen's Toner map&lt;/a&gt;. The shape (also available &lt;a href="https://github.com/stamen/toner-carto/blob/master/shp-local/nullisland.geojson"&gt;as GeoJSON&lt;/a&gt;) is an homage to the island from 1993's &lt;a href="https://en.wikipedia.org/wiki/Myst"&gt;Myst&lt;/a&gt;, hence the outline of a large docked ship at the bottom.&lt;/p&gt;
&lt;p&gt;&lt;img alt="White outline of Null Island on a black background." src="https://static.simonwillison.net/static/2024/null-island-toner.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Alan recently gave a talk about Stamen's updated custom maps at State of the Map US 2024 (&lt;a href="https://www.youtube.com/watch?v=qewW7-z8W2I"&gt;video&lt;/a&gt;, &lt;a href="https://speakerdeck.com/almccon/rebuilding-stamens-iconic-map-styles-with-stadia-maps"&gt;slides&lt;/a&gt;) - their Toner and Terrain maps are now available as vector tiles served by Stadia Maps (here's &lt;a href="https://stamen.com/stamen-x-stadia-the-end-of-the-road-for-stamens-legacy-map-tiles/"&gt;the announcement&lt;/a&gt;), but their iconic watercolor style is yet to be updated to vectors, due to the weird array of raster tricks it used to achieve the effect.&lt;/p&gt;
&lt;p&gt;In researching this post I searched for &lt;a href="https://www.google.com/maps/search/null+island/@6.3431564,-0.774215,5.21z"&gt;null island on Google Maps&lt;/a&gt; and was delighted to learn that a bunch of entrepreneurs in Western Africa have tapped into the meme for their own businesses:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A null island search returns companies in The Gambia, Côte d’Ivoire, Burkina Faso, Cameroon and Democratic Republic of the Congo." src="https://static.simonwillison.net/static/2024/null-island-google-maps.jpg" /&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://waxy.org/2024/07/the-many-lives-of-null-island/"&gt;Andy Baio&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/michal-migurski"&gt;michal-migurski&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/stamen-design"&gt;stamen-design&lt;/a&gt;&lt;/p&gt;



</summary><category term="geospatial"/><category term="maps"/><category term="michal-migurski"/><category term="stamen-design"/></entry><entry><title>How to make self-hosted maps that work everywhere and cost next to nothing</title><link href="https://simonwillison.net/2024/Feb/24/self-hosted-maps/#atom-tag" rel="alternate"/><published>2024-02-24T04:19:05+00:00</published><updated>2024-02-24T04:19:05+00:00</updated><id>https://simonwillison.net/2024/Feb/24/self-hosted-maps/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.muckrock.com/news/archives/2024/feb/13/release-notes-how-to-make-self-hosted-maps-that-work-everywhere-cost-next-to-nothing-and-might-even-work-in-airplane-mode/"&gt;How to make self-hosted maps that work everywhere and cost next to nothing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Chris Amico provides a detailed roundup of the state of web mapping in 2024. It’s never been easier to entirely host your own mapping infrastructure, thanks to OpenStreetMap, Overture, MBTiles, PMTiles, Maplibre and a whole ecosystem of other fine open source projects.&lt;/p&gt;

&lt;p&gt;I like Protomaps creator Brandon Liu’s description of this: “post-scarcity web mapping”.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chris-amico"&gt;chris-amico&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/overture"&gt;overture&lt;/a&gt;&lt;/p&gt;



</summary><category term="geospatial"/><category term="maps"/><category term="chris-amico"/><category term="overture"/></entry><entry><title>How The Post is replacing Mapbox with open source solutions</title><link href="https://simonwillison.net/2023/Feb/17/replacing-mapbox/#atom-tag" rel="alternate"/><published>2023-02-17T18:45:33+00:00</published><updated>2023-02-17T18:45:33+00:00</updated><id>https://simonwillison.net/2023/Feb/17/replacing-mapbox/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.kschaul.com/post/2023/02/16/how-the-post-is-replacing-mapbox-with-open-source-solutions/"&gt;How The Post is replacing Mapbox with open source solutions&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Kevin Schaul describes the Washington Post’s emerging open source GIS stack: OpenMapTiles, Maputnik, PMTiles and Maplibre-gl-js.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=34836700"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/opensearch"&gt;opensearch&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/washington-post"&gt;washington-post&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/><category term="opensearch"/><category term="openstreetmap"/><category term="washington-post"/></entry><entry><title>A tiny web app to create images from OpenStreetMap maps</title><link href="https://simonwillison.net/2022/Jun/12/url-map/#atom-tag" rel="alternate"/><published>2022-06-12T05:49:35+00:00</published><updated>2022-06-12T05:49:35+00:00</updated><id>https://simonwillison.net/2022/Jun/12/url-map/#atom-tag</id><summary type="html">
    &lt;p&gt;Earlier today I found myself wanting to programmatically generate some images of maps.&lt;/p&gt;
&lt;p&gt;I wanted to create a map centered around a location, at a specific zoom level, and with a marker in a specific place.&lt;/p&gt;
&lt;p&gt;Some cursory searches failed to turn up exactly what I wanted, so I decided to build a tiny project to solve the problem, taking advantage of my &lt;a href="https://shot-scraper.datasette.io/"&gt;shot-scraper tool&lt;/a&gt; for automating screenshots of web pages.&lt;/p&gt;
&lt;p&gt;The result is &lt;a href="https://map.simonwillison.net/"&gt;map.simonwillison.net&lt;/a&gt; - hosted on GitHub Pages from my &lt;a href="https://github.com/simonw/url-map"&gt;simonw/url-map&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;Here's how to generate a map image of Washington DC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shot-scraper 'https://map.simonwillison.net/?q=washington+dc' \
  --retina --width 600 --height 400 --wait 3000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That command generates a PNG 1200x800 image that's a retina screenshot of the map displayed at &lt;a href="https://map.simonwillison.net/?q=washington+dc"&gt;https://map.simonwillison.net/?q=washington+dc&lt;/a&gt; - after waiting three seconds to esure all of the tiles have fully loaded.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2022/map-simonwillison-net.jpg" alt="A map of Washington DC, with a Leaflet / OpenStreetMap attribution in the bottom right" style="max-width:100%;" /&gt;&lt;/p&gt;
&lt;p&gt;The website itself is &lt;a href="https://github.com/simonw/url-map/blob/main/README.md"&gt;documented here&lt;/a&gt;. It displays a map with no visible controls, though you can use gestures to zoom in and pan around - and the URL bar will update to reflect your navigation, so you can bookmark or share the URL once you've got it to the right spot.&lt;/p&gt;
&lt;p&gt;You can also use query string parameters to specify the map that should be initially displayed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://map.simonwillison.net/?center=51.49,0&amp;amp;zoom=8"&gt;https://map.simonwillison.net/?center=51.49,0&amp;amp;zoom=8&lt;/a&gt; displays a map at zoom level 8 centered on the specified latitude, longitude coordinate pair.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://map.simonwillison.net/?q=islington+london"&gt;https://map.simonwillison.net/?q=islington+london&lt;/a&gt; geocodes the &lt;code&gt;?q=&lt;/code&gt; text using &lt;a href="https://nominatim.openstreetmap.org/ui/search.html"&gt;OpenStreetMap Nominatim&lt;/a&gt; and zooms to the level that best fits the bounding box of the first returned result.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://map.simonwillison.net/?q=islington+london&amp;amp;zoom=12"&gt;https://map.simonwillison.net/?q=islington+london&amp;amp;zoom=12&lt;/a&gt; does that but zooms to level 12 instead of using the best fit for the bounding box&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://map.simonwillison.net/?center=51.49,0&amp;amp;zoom=8&amp;amp;marker=51.49,0&amp;amp;marker=51.3,0.2"&gt;https://map.simonwillison.net/?center=51.49,0&amp;amp;zoom=8&amp;amp;marker=51.49,0&amp;amp;marker=51.3,0.2&lt;/a&gt; adds two blue markers to the specified map. You can pass &lt;code&gt;&amp;amp;marker=lat,lon&lt;/code&gt; as many times as you like to add multiple markers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Annotated source code&lt;/h4&gt;
&lt;p&gt;The entire mapping application is contained in a single 68 line &lt;code&gt;index.html&lt;/code&gt; file that mixes HTML and JavaScript. It's built using the fantastic &lt;a href="https://leafletjs.com/"&gt;Leaflet&lt;/a&gt; open source mapping library.&lt;/p&gt;
&lt;p&gt;Since the code is so short, I'll enclude the entire thing here with some additional annotating comments.&lt;/p&gt;
&lt;p&gt;It started out as a copy of the first example in &lt;a href="https://leafletjs.com/examples/quick-start/"&gt;the Leaflet quick start guide&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight highlight-text-html-basic"&gt;&lt;pre&gt;&lt;span class="pl-c1"&gt;&amp;lt;!DOCTYPE html&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&amp;lt;!-- Regular HTML boilerplate --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;html&lt;/span&gt; &lt;span class="pl-c1"&gt;lang&lt;/span&gt;="&lt;span class="pl-s"&gt;en&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;head&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;meta&lt;/span&gt; &lt;span class="pl-c1"&gt;charset&lt;/span&gt;="&lt;span class="pl-s"&gt;utf-8&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;meta&lt;/span&gt; &lt;span class="pl-c1"&gt;name&lt;/span&gt;="&lt;span class="pl-s"&gt;viewport&lt;/span&gt;" &lt;span class="pl-c1"&gt;content&lt;/span&gt;="&lt;span class="pl-s"&gt;width=device-width, initial-scale=1&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;title&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;map.simonwillison.net&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;title&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&amp;lt;!--&lt;/span&gt;
&lt;span class="pl-c"&gt;  Leaflet's CSS and JS are loaded from the unpgk.com CDN, with the&lt;/span&gt;
&lt;span class="pl-c"&gt;  Subresource Integrity (SRI) integrity="sha512..." attribute to ensure&lt;/span&gt;
&lt;span class="pl-c"&gt;  that the exact expected code is served by the CDN.&lt;/span&gt;
&lt;span class="pl-c"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;link&lt;/span&gt; &lt;span class="pl-c1"&gt;rel&lt;/span&gt;="&lt;span class="pl-s"&gt;stylesheet&lt;/span&gt;" &lt;span class="pl-c1"&gt;href&lt;/span&gt;="&lt;span class="pl-s"&gt;https://unpkg.com/leaflet@1.8.0/dist/leaflet.css&lt;/span&gt;" &lt;span class="pl-c1"&gt;integrity&lt;/span&gt;="&lt;span class="pl-s"&gt;sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==&lt;/span&gt;" &lt;span class="pl-c1"&gt;crossorigin&lt;/span&gt;=""/&amp;gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt; &lt;span class="pl-c1"&gt;src&lt;/span&gt;="&lt;span class="pl-s"&gt;https://unpkg.com/leaflet@1.8.0/dist/leaflet.js&lt;/span&gt;" &lt;span class="pl-c1"&gt;integrity&lt;/span&gt;="&lt;span class="pl-s"&gt;sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==&lt;/span&gt;" &lt;span class="pl-c1"&gt;crossorigin&lt;/span&gt;=""&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&amp;lt;!-- I want the map to occupy the entire browser window with no margins --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-ent"&gt;html&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-ent"&gt;body&lt;/span&gt; {
  &lt;span class="pl-c1"&gt;height&lt;/span&gt;&lt;span class="pl-kos"&gt;:&lt;/span&gt; &lt;span class="pl-c1"&gt;100&lt;span class="pl-smi"&gt;%&lt;/span&gt;&lt;/span&gt;;
  &lt;span class="pl-c1"&gt;margin&lt;/span&gt;&lt;span class="pl-kos"&gt;:&lt;/span&gt; &lt;span class="pl-c1"&gt;0&lt;/span&gt;;
}
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;head&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;body&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&amp;lt;!-- The Leaflet map renders in this 100% high/wide div --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;div&lt;/span&gt; &lt;span class="pl-c1"&gt;id&lt;/span&gt;="&lt;span class="pl-s"&gt;map&lt;/span&gt;" &lt;span class="pl-c1"&gt;style&lt;/span&gt;="&lt;span class="pl-s"&gt;width: 100%; height: 100%;&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;div&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-en"&gt;toPoint&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;s&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-c"&gt;// Convert "51.5,2.1" into [51.5, 2.1]&lt;/span&gt;
  &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-s1"&gt;s&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;split&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;","&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;parseFloat&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;
&lt;span class="pl-c"&gt;// An async function so we can 'await fetch(...)' later on&lt;/span&gt;
&lt;span class="pl-k"&gt;async&lt;/span&gt; &lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-en"&gt;load&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-c"&gt;// URLSearchParams is a fantastic browser API - it makes it easy to both read&lt;/span&gt;
  &lt;span class="pl-c"&gt;// query string parameters from the URL and later to generate new ones&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;params&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;URLSearchParams&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;location&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;search&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// If the starting URL is /?center=51,32&amp;amp;zoom=3 this will pull those values out&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;center&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;params&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;get&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'center'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-c1"&gt;||&lt;/span&gt; &lt;span class="pl-s"&gt;'0,0'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;initialZoom&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;params&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;get&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'zoom'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;zoom&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;parseInt&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;initialZoom&lt;/span&gt; &lt;span class="pl-c1"&gt;||&lt;/span&gt; &lt;span class="pl-s"&gt;'2'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-c1"&gt;10&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;q&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;params&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;get&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'q'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// .getAll() turns &amp;amp;marker=51.49,0&amp;amp;marker=51.3,0.2 into ['51.49,0', '51.3,0.2']&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;markers&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;params&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getAll&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'marker'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// zoomControl: false turns off the visible +/- zoom buttons in Leaflet&lt;/span&gt;
  &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;map&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-v"&gt;L&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'map'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-c1"&gt;zoomControl&lt;/span&gt;: &lt;span class="pl-c1"&gt;false&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;setView&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-en"&gt;toPoint&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;center&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;zoom&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-v"&gt;L&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;tileLayer&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;maxZoom&lt;/span&gt;: &lt;span class="pl-c1"&gt;19&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-c1"&gt;attribution&lt;/span&gt;: &lt;span class="pl-s"&gt;'&amp;amp;copy; &amp;lt;a href="http://www.openstreetmap.org/copyright"&amp;gt;OpenStreetMap&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-c"&gt;// This option means retina-capable devices will get double-resolution tiles:&lt;/span&gt;
    &lt;span class="pl-c1"&gt;detectRetina&lt;/span&gt;: &lt;span class="pl-c1"&gt;true&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;addTo&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// We only pay attention to ?q= if ?center= was not provided:&lt;/span&gt;
  &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;q&lt;/span&gt; &lt;span class="pl-c1"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="pl-c1"&gt;!&lt;/span&gt;&lt;span class="pl-s1"&gt;params&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;get&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'center'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c"&gt;// We use fetch to pass ?q= to the Nominatim API and get back JSON&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;response&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-en"&gt;fetch&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;
      &lt;span class="pl-s"&gt;`https://nominatim.openstreetmap.org/search.php?q=&lt;span class="pl-s1"&gt;&lt;span class="pl-kos"&gt;${&lt;/span&gt;&lt;span class="pl-en"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;q&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;/span&gt;&amp;amp;format=jsonv2`&lt;/span&gt;
    &lt;span class="pl-kos"&gt;)&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;data&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-s1"&gt;response&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;json&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// data[0] is the first result - it has a boundingbox array of four floats&lt;/span&gt;
    &lt;span class="pl-c"&gt;// which we can convert into a Leaflet-compatible bounding box like this:&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;bounds&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-kos"&gt;[&lt;/span&gt;
      &lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;0&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;boundingbox&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;0&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;0&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;boundingbox&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;2&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;0&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;boundingbox&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;1&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;0&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;boundingbox&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-c1"&gt;3&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;
    &lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// This sets both the map center and zooms to the correct level for the bbox:&lt;/span&gt;
    &lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;fitBounds&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;bounds&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// User-provided zoom over-rides this&lt;/span&gt;
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;initialZoom&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;setZoom&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-en"&gt;parseInt&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;initialZoom&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c"&gt;// This is the code that updates the URL as the user pans or zooms around.&lt;/span&gt;
  &lt;span class="pl-c"&gt;// You can subscribe to both the moveend and zoomend Leaflet events in one go:&lt;/span&gt;
  &lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;on&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'moveend zoomend'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c"&gt;// Update URL bar with current location&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;newZoom&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getZoom&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;center&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getCenter&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// This time we use URLSearchParams to construct a center...=&amp;amp;zoom=... URL&lt;/span&gt;
    &lt;span class="pl-k"&gt;let&lt;/span&gt; &lt;span class="pl-s1"&gt;u&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;URLSearchParams&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// Copy across ?marker=x&amp;amp;marker=y from existing URL, if they were set:&lt;/span&gt;
    &lt;span class="pl-s1"&gt;markers&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;forEach&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;s&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s1"&gt;u&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;append&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'marker'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;s&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-s1"&gt;u&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;append&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'center'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s"&gt;`&lt;span class="pl-s1"&gt;&lt;span class="pl-kos"&gt;${&lt;/span&gt;&lt;span class="pl-s1"&gt;center&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;lat&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;/span&gt;,&lt;span class="pl-s1"&gt;&lt;span class="pl-kos"&gt;${&lt;/span&gt;&lt;span class="pl-s1"&gt;center&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;lng&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;/span&gt;`&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-s1"&gt;u&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;append&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'zoom'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;newZoom&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-c"&gt;// replaceState() is a weird API - the third argument is the one we care about:&lt;/span&gt;
    &lt;span class="pl-s1"&gt;history&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;replaceState&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-c1"&gt;null&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-c1"&gt;null&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s"&gt;'?'&lt;/span&gt; &lt;span class="pl-c1"&gt;+&lt;/span&gt; &lt;span class="pl-s1"&gt;u&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;toString&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// This bit adds Leaflet markers to the map for ?marker= query string arguments:&lt;/span&gt;
  &lt;span class="pl-s1"&gt;markers&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;forEach&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;s&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-v"&gt;L&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;marker&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-en"&gt;toPoint&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;s&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;addTo&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;map&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;
&lt;span class="pl-en"&gt;load&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;body&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;html&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&amp;lt;!-- See https://github.com/simonw/url-map for documentation --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/shot-scraper"&gt;shot-scraper&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/leaflet"&gt;leaflet&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="geospatial"/><category term="maps"/><category term="openstreetmap"/><category term="projects"/><category term="shot-scraper"/><category term="leaflet"/></entry><entry><title>Apple’s New Map</title><link href="https://simonwillison.net/2018/Nov/3/apples-new-map/#atom-tag" rel="alternate"/><published>2018-11-03T21:28:14+00:00</published><updated>2018-11-03T21:28:14+00:00</updated><id>https://simonwillison.net/2018/Nov/3/apples-new-map/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.justinobeirne.com/new-apple-maps"&gt;Apple’s New Map&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Map nerds rejoice! Justin O’Beirne had written another spectacularly illustrated essay about web cartography, this time examining the iOS 12 upgrade to Apple Maps in most of California and a little bit of Nevada.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://daringfireball.net/linked/2018/11/02/apples-new-map"&gt;Daring Fireball&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/></entry><entry><title>Datasette plugins, and building a clustered map visualization</title><link href="https://simonwillison.net/2018/Apr/20/datasette-plugins/#atom-tag" rel="alternate"/><published>2018-04-20T15:41:11+00:00</published><updated>2018-04-20T15:41:11+00:00</updated><id>https://simonwillison.net/2018/Apr/20/datasette-plugins/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;a href="https://github.com/simonw/datasette"&gt;Datasette&lt;/a&gt; now supports plugins!&lt;/p&gt;
&lt;p&gt;Last Saturday &lt;a href="https://twitter.com/simonw/status/985377670388105216"&gt;I asked Twitter&lt;/a&gt; for examples of Python projects with successful plugin ecosystems. &lt;a href="https://docs.pytest.org/"&gt;pytest&lt;/a&gt; was the clear winner: the &lt;a href="https://plugincompat.herokuapp.com/"&gt;pytest plugin compatibility table&lt;/a&gt; (an ingenious innovation that I would love to eventually copy for Datasette) lists 457 plugins, and even the core pytest system itself is built as a collection of default plugins that can be replaced or over-ridden.&lt;/p&gt;
&lt;p&gt;Best of all: pytest’s plugin mechanism is available as a separate package: &lt;a href="https://pluggy.readthedocs.io/"&gt;pluggy&lt;/a&gt;. And pluggy was exactly what I needed for Datasette.&lt;/p&gt;
&lt;p&gt;You can follow the ongoing development of the feature in issue &lt;a href="https://github.com/simonw/datasette/issues/14"&gt;#14&lt;/a&gt;. This morning I released &lt;a href="https://github.com/simonw/datasette/releases/tag/0.20"&gt;Datasette 0.20&lt;/a&gt; with support for a number of different plugin hooks: plugins can add custom template tags and SQL functions, and can also bundle their own static assets, JavaScript, CSS and templates. The hooks are described in some detail in the &lt;a href="https://datasette.readthedocs.io/en/latest/plugins.html"&gt;Datasette Plugins&lt;/a&gt; documentation.&lt;/p&gt;
&lt;h2&gt;&lt;a id="datasetteclustermap_10"&gt;&lt;/a&gt;datasette-cluster-map&lt;/h2&gt;
&lt;p&gt;I also released my first plugin: &lt;a href="https://pypi.org/project/datasette-cluster-map/"&gt;datasette-cluster-map&lt;/a&gt;. Once installed, it looks out for database tables that have a &lt;code&gt;latitude&lt;/code&gt; and &lt;code&gt;longitude&lt;/code&gt; column. When it finds them, it draws all of the points on an interactive map using &lt;a href="http://leafletjs.com/"&gt;Leaflet&lt;/a&gt; and &lt;a href="https://github.com/Leaflet/Leaflet.markercluster"&gt;Leaflet.markercluster&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s &lt;a href="https://datasette-cluster-map-demo.now.sh/polar-bears-455fe3a/USGS_WC_eartags_output_files_2009-2011-Status"&gt;try it out on some polar bears&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;img style="width: 100%" src="https://static.simonwillison.net/static/2018/polar-bears-cluster-map.gif" alt="Polar Bears on a cluster map"/&gt;&lt;/p&gt;
&lt;p&gt;The USGS Alaska Science Center have released a delightful set of data entitled &lt;a href="https://alaska.usgs.gov/products/data.php?dataid=130"&gt;Sensor and Location data from Ear Tag PTTs Deployed on Polar Bears in the Southern Beaufort Sea 2009 to 2011&lt;/a&gt;. It’s a collection of CSV files, which means it’s &lt;a href="https://gist.github.com/simonw/9f8bf23b37a42d7628c4dcc4bba10253"&gt;trivial to convert it to SQLite&lt;/a&gt; using my &lt;a href="https://github.com/simonw/csvs-to-sqlite"&gt;csvs-to-sqlite&lt;/a&gt; tool.&lt;/p&gt;
&lt;p&gt;Having created the SQLite database, we can deploy it to a hosting account on &lt;a href="https://zeit.co/now"&gt;Zeit Now&lt;/a&gt; alongside the new plugin like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Make sure we have the latest datasette
pip3 install datasette --upgrade
# Deploy polar-bears.db to now with an increased default page_size
datasette publish now \
    --install=datasette-cluster-map \
    --extra-options &amp;quot;--page_size=500&amp;quot; \
    polar-bears.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;--install&lt;/code&gt; option is new in Datasette 0.20 (it works for &lt;code&gt;datasette publish heroku&lt;/code&gt; as well) - it tells the publishing provider to &lt;code&gt;pip install&lt;/code&gt; the specified package. You can use it more than once to install multiple plugins, and it accepts a path to a zip file in addition to the name of a PyPI package.&lt;/p&gt;
&lt;p&gt;Explore the full demo at &lt;a href="https://datasette-cluster-map-demo.now.sh/polar-bears"&gt;https://datasette-cluster-map-demo.now.sh/polar-bears&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a id="Visualize_any_query_on_a_map_35"&gt;&lt;/a&gt;Visualize any query on a map&lt;/h2&gt;
&lt;p&gt;Since the plugin inserts itself at the top of any Datasette table view with &lt;code&gt;latitude&lt;/code&gt; and &lt;code&gt;longitude&lt;/code&gt; columns, there are all sorts of neat tricks you can do with it.&lt;/p&gt;
&lt;p&gt;I also loaded the San Francisco tree list (thanks, &lt;a href="https://data.sfgov.org/City-Infrastructure/Street-Tree-List/tkzw-k3nq"&gt;Department of Public Works&lt;/a&gt;) into the demo. Impressively, you can click “load all” &lt;a href="https://datasette-cluster-map-demo.now.sh/sf-trees-02c8ef1/Street_Tree_List"&gt;on this page&lt;/a&gt; and &lt;code&gt;Leaflet.markercluster&lt;/code&gt; will load in all 189,144 points and display them on the same map… and it works fine on my laptop and my phone. Computers in 2018 are pretty good!&lt;/p&gt;
&lt;p&gt;But since it’s a Datasette table, we can filter it. Here’s a map of &lt;a href="https://datasette-cluster-map-demo.now.sh/sf-trees-02c8ef1/Street_Tree_List?qSpecies=2"&gt;every New Zealand Xmas Tree&lt;/a&gt; in San Francisco (8,683 points). Here’s &lt;a href="https://datasette-cluster-map-demo.now.sh/sf-trees-02c8ef1/Street_Tree_List?qCareAssistant=1"&gt;every tree where the Caretaker is Friends of the Urban Forest&lt;/a&gt;. Here’s &lt;a href="https://datasette-cluster-map-demo.now.sh/sf-trees-02c8ef1/Street_Tree_List?PlantDate__contains=1990&amp;amp;_search=palm&amp;amp;_sort=qLegalStatus"&gt;every palm tree planted in 1990&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img style="width: 100%" src="https://static.simonwillison.net/static/2018/datasette-palm-trees-1990.png" alt="Palm trees planted in 1990" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This is an incorrect example: there are 21 matches on "palm avenue" because the FTS search index covers the address field - they're not actually palm trees. Here's a corrected query for &lt;a href="https://datasette-cluster-map-demo.now.sh/sf-trees-02c8ef1?sql=select+PlantDate%2C+Street_Tree_List.rowid%2C+latitude%2C+longitude%2C+qSpecies.value%0D%0Afrom+Street_Tree_List+join+qSpecies+on+Street_Tree_List.qSpecies+%3D+qSpecies.id%0D%0Awhere+qSpecies.value+like+%22%25palm%25%22+and+PlantDate+like+%22%251990%25%22"&gt;palm trees planted in 1990&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The plugin currently only works against columns called &lt;code&gt;latitude&lt;/code&gt; and &lt;code&gt;longitude&lt;/code&gt;… but if your columns are called something else, don’t worry: you can craft a custom SQL query that aliases your columns and everything will work as intended. Here’s an example &lt;a href="https://datasette-cluster-map-demo.now.sh/polar-bears-455fe3a?sql=select+*%2C+%22Capture+Latitude%22+as+latitude%2C+%22Capture+Longitude%22+as+longitude%0D%0Afrom+%5BUSGS_WC_eartag_deployments_2009-2011%5D"&gt;against some more polar bear data&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select *, &amp;quot;Capture Latitude&amp;quot; as latitude, &amp;quot;Capture Longitude&amp;quot; as longitude
from [USGS_WC_eartag_deployments_2009-2011]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a id="Writing_your_own_plugins_50"&gt;&lt;/a&gt;Writing your own plugins&lt;/h2&gt;
&lt;p&gt;I’m really excited to see what people invent. If you want to have a go, your first stop should be the &lt;a href="https://datasette.readthedocs.io/en/latest/plugins.html"&gt;Plugins documentation&lt;/a&gt;. If you want an example of a simple plugin (including the all-important mechanism for packaging it up using &lt;code&gt;setup.py&lt;/code&gt;) take a look at &lt;a href="https://github.com/simonw/datasette-cluster-map"&gt;datasette-cluster-map&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;p&gt;And if you have any thoughts, ideas or suggestions on how the plugin mechanism can be further employed please join the conversation on &lt;a href="https://github.com/simonw/datasette/issues/14"&gt;issue #14&lt;/a&gt;. I’ve literally just got started with Datasette’s plugin hooks, and I’m very keen to hear about things people want to build that aren’t yet supported.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/plugins"&gt;plugins&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/visualization"&gt;visualization&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette"&gt;datasette&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pytest"&gt;pytest&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/leaflet"&gt;leaflet&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="maps"/><category term="plugins"/><category term="projects"/><category term="visualization"/><category term="datasette"/><category term="pytest"/><category term="leaflet"/></entry><entry><title>Is there an open source (or freely accessible) database of geofence coordinates for common places, such as cities or national parks?</title><link href="https://simonwillison.net/2013/Dec/3/is-there-an-open/#atom-tag" rel="alternate"/><published>2013-12-03T12:59:00+00:00</published><updated>2013-12-03T12:59:00+00:00</updated><id>https://simonwillison.net/2013/Dec/3/is-there-an-open/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;em&gt;My answer to &lt;a href="https://www.quora.com/Is-there-an-open-source-or-freely-accessible-database-of-geofence-coordinates-for-common-places-such-as-cities-or-national-parks/answer/Simon-Willison"&gt;Is there an open source (or freely accessible) database of geofence coordinates for common places, such as cities or national parks?&lt;/a&gt; on Quora&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Take a look at Flickr's openly licensed shapefiles:&lt;/p&gt;

&lt;span&gt;&lt;a href="http://code.flickr.net/2011/01/08/flickr-shapefiles-public-dataset-2-0/"&gt;http://code.flickr.net/2011/01/0...&lt;/a&gt;&lt;/span&gt;

&lt;p&gt;They are derived from the collective opinion of Flickr's community as to what name should apply to different areas around the world.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/databases"&gt;databases&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geolocation"&gt;geolocation&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/location"&gt;location&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="databases"/><category term="geolocation"/><category term="google-maps"/><category term="location"/><category term="maps"/><category term="open-source"/><category term="quora"/></entry><entry><title>Does the Google Maps API let you remove details of the map such as street names to focus on pins on the map?</title><link href="https://simonwillison.net/2013/Nov/12/does-the-google-maps/#atom-tag" rel="alternate"/><published>2013-11-12T14:33:00+00:00</published><updated>2013-11-12T14:33:00+00:00</updated><id>https://simonwillison.net/2013/Nov/12/does-the-google-maps/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;em&gt;My answer to &lt;a href="https://www.quora.com/Does-the-Google-Maps-API-let-you-remove-details-of-the-map-such-as-street-names-to-focus-on-pins-on-the-map/answer/Simon-Willison"&gt;Does the Google Maps API let you remove details of the map such as street names to focus on pins on the map?&lt;/a&gt; on Quora&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yes - you can do this with map styles (which allow you to set the visibility if road labels, among other things): &lt;span&gt;&lt;a href="http://developers.google.com/maps/documentation/javascript/styling"&gt;http://developers.google.com/map...&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/apis"&gt;apis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="apis"/><category term="google-maps"/><category term="maps"/><category term="quora"/></entry><entry><title>Cartographer.js</title><link href="https://simonwillison.net/2009/Nov/1/cartographerjs/#atom-tag" rel="alternate"/><published>2009-11-01T13:20:05+00:00</published><updated>2009-11-01T13:20:05+00:00</updated><id>https://simonwillison.net/2009/Nov/1/cartographerjs/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cartographer.visualmotive.com/"&gt;Cartographer.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Thematic mapping for Google Maps”—which means an easy way of adding heat maps (aka chloropleths), pie charts and point clusters as a layer over a Google map.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/catography"&gt;catography&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chloropleths"&gt;chloropleths&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphs"&gt;graphs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/heatmaps"&gt;heatmaps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/infographics"&gt;infographics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/piecharts"&gt;piecharts&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/visualisation"&gt;visualisation&lt;/a&gt;&lt;/p&gt;



</summary><category term="catography"/><category term="chloropleths"/><category term="google"/><category term="google-maps"/><category term="graphs"/><category term="heatmaps"/><category term="infographics"/><category term="mapping"/><category term="maps"/><category term="piecharts"/><category term="visualisation"/></entry><entry><title>Best of OpenStreetMap</title><link href="https://simonwillison.net/2009/Aug/13/osm/#atom-tag" rel="alternate"/><published>2009-08-13T12:30:05+00:00</published><updated>2009-08-13T12:30:05+00:00</updated><id>https://simonwillison.net/2009/Aug/13/osm/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://bestofosm.org/"&gt;Best of OpenStreetMap&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I keep on telling people OpenStreetMap is this year’s Wikipedia—at its best, it beats commercially available maps. This “best of” site highlights the areas where OSM really shines (the yellow stars)—the German mapping community in particular have produced some outstanding cartography.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://www.opengeodata.org/?p=647"&gt;OpenGeoData&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/cartography"&gt;cartography&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/wikipedia"&gt;wikipedia&lt;/a&gt;&lt;/p&gt;



</summary><category term="cartography"/><category term="mapping"/><category term="maps"/><category term="openstreetmap"/><category term="wikipedia"/></entry><entry><title>Making Image Overlays Easy with GGroundOverlay and GGeoXML</title><link href="https://simonwillison.net/2009/Jul/30/overlays/#atom-tag" rel="alternate"/><published>2009-07-30T22:58:04+00:00</published><updated>2009-07-30T22:58:04+00:00</updated><id>https://simonwillison.net/2009/Jul/30/overlays/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://googlemapsapi.blogspot.com/2007/05/v280-making-image-overlays-easy-with.html"&gt;Making Image Overlays Easy with GGroundOverlay and GGeoXML&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Surprisingly, there doesn’t appear to be a good online tool for helping align an overlay image with a Google Map and exporting the result as a KML file. This is the best I could find—Yahoo! used to have a tool called MapMixer but it doesn’t seem to exist any more.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://twitter.com/psychemedia/status/2934986818"&gt;Tony Hirst&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/overlays"&gt;overlays&lt;/a&gt;&lt;/p&gt;



</summary><category term="google-maps"/><category term="maps"/><category term="overlays"/></entry><entry><title>Flickr Shapefiles Public Dataset 1.0</title><link href="https://simonwillison.net/2009/May/22/shapefiles/#atom-tag" rel="alternate"/><published>2009-05-22T18:12:10+00:00</published><updated>2009-05-22T18:12:10+00:00</updated><id>https://simonwillison.net/2009/May/22/shapefiles/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://code.flickr.com/blog/2009/05/21/flickr-shapefiles-public-dataset-10/"&gt;Flickr Shapefiles Public Dataset 1.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Another awesome Geo dataset from the Yahoo! stable—this time it’s Flickr releasing shapefiles (geometrical shapes) for hundreds of thousands of places around the world, under the CC0 license which makes them essentially public domain. The shapes themselves have been crowdsourced from geocoded photos uploaded to Flickr, where users can “correct” the textual location assigned to each photo. Combine this with the GeoPlanet WOE data and you get a huge, free dataset describing the human geography of the world.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/creativecommons"&gt;creativecommons&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/crowdsourcing"&gt;crowdsourcing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flickr"&gt;flickr&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geoplanet"&gt;geoplanet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/shapefiles"&gt;shapefiles&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/yahoo"&gt;yahoo&lt;/a&gt;&lt;/p&gt;



</summary><category term="creativecommons"/><category term="crowdsourcing"/><category term="flickr"/><category term="geoplanet"/><category term="geospatial"/><category term="maps"/><category term="shapefiles"/><category term="yahoo"/></entry><entry><title>UK Television Series Map</title><link href="https://simonwillison.net/2009/Apr/5/uktv/#atom-tag" rel="alternate"/><published>2009-04-05T19:25:25+00:00</published><updated>2009-04-05T19:25:25+00:00</updated><id>https://simonwillison.net/2009/Apr/5/uktv/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://meish.org/2009/04/05/uk-tv-series-map/comment-page-1/#comment-46935"&gt;UK Television Series Map&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Inspired by the US sitcom map, Meg Pickard is plotting TV series on a map of the UK.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/meg-pickard"&gt;meg-pickard&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tv"&gt;tv&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/><category term="meg-pickard"/><category term="tv"/></entry><entry><title>1901EasternTelegraph.jpg</title><link href="https://simonwillison.net/2009/Feb/9/undersea/#atom-tag" rel="alternate"/><published>2009-02-09T20:44:00+00:00</published><updated>2009-02-09T20:44:00+00:00</updated><id>https://simonwillison.net/2009/Feb/9/undersea/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.atlantic-cable.com/Maps/1901EasternTelegraph.jpg"&gt;1901EasternTelegraph.jpg&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
A map of undersea telegraph cables as of 1901.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://blog.clintecker.com/post/76903570/via-map-of-undersea-telegraph-cables-as-of-1901"&gt;Clint Ecker&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/cables"&gt;cables&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/undersea"&gt;undersea&lt;/a&gt;&lt;/p&gt;



</summary><category term="cables"/><category term="maps"/><category term="undersea"/></entry><entry><title>Travel time to major cities: A global map of Accessibility</title><link href="https://simonwillison.net/2009/Jan/5/travel/#atom-tag" rel="alternate"/><published>2009-01-05T13:24:51+00:00</published><updated>2009-01-05T13:24:51+00:00</updated><id>https://simonwillison.net/2009/Jan/5/travel/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://gem.jrc.ec.europa.eu/gam/index.htm"&gt;Travel time to major cities: A global map of Accessibility&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Visualisation developed by the European Commission and the World Bank.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://mike.teczno.com/snippets.html"&gt;Michal Migurski&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/accessibility"&gt;accessibility&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/europeancommission"&gt;europeancommission&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/visualisation"&gt;visualisation&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/worldbank"&gt;worldbank&lt;/a&gt;&lt;/p&gt;



</summary><category term="accessibility"/><category term="europeancommission"/><category term="maps"/><category term="visualisation"/><category term="worldbank"/></entry><entry><title>Motorway map of England, Scotland and Wales</title><link href="https://simonwillison.net/2008/Dec/22/motorway/#atom-tag" rel="alternate"/><published>2008-12-22T11:36:58+00:00</published><updated>2008-12-22T11:36:58+00:00</updated><id>https://simonwillison.net/2008/Dec/22/motorway/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://motorwaymap.co.uk/"&gt;Motorway map of England, Scotland and Wales&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
In the style of Harry Beck’s London Tube map.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://www.iamcal.com/linklog/1229728806/"&gt;Cal&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/motorways"&gt;motorways&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tubemap"&gt;tubemap&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/><category term="motorways"/><category term="tubemap"/></entry><entry><title>Noncontiguous area cartograms</title><link href="https://simonwillison.net/2008/Dec/8/indiemapscomblog/#atom-tag" rel="alternate"/><published>2008-12-08T18:03:08+00:00</published><updated>2008-12-08T18:03:08+00:00</updated><id>https://simonwillison.net/2008/Dec/8/indiemapscomblog/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/"&gt;Noncontiguous area cartograms&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
a.k.a. really funky data visualisation maps. Includes lots of examples, plus ActionScript 3 source code.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/as3"&gt;as3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cartograms"&gt;cartograms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flash"&gt;flash&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/visualisation"&gt;visualisation&lt;/a&gt;&lt;/p&gt;



</summary><category term="as3"/><category term="cartograms"/><category term="flash"/><category term="maps"/><category term="visualisation"/></entry><entry><title>Live Piracy Map</title><link href="https://simonwillison.net/2008/Dec/1/piracy/#atom-tag" rel="alternate"/><published>2008-12-01T00:29:25+00:00</published><updated>2008-12-01T00:29:25+00:00</updated><id>https://simonwillison.net/2008/Dec/1/piracy/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.icc-ccs.org/index.php?option=com_fabrik&amp;amp;view=visualization&amp;amp;controller=visualization.googlemap&amp;amp;Itemid=89"&gt;Live Piracy Map&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
That’s a heck of a lot of (real, nasty, sea-faring) pirates.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pirates"&gt;pirates&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/><category term="pirates"/></entry><entry><title>FOWA London - Beyond GoogleMaps</title><link href="https://simonwillison.net/2008/Oct/17/fowa/#atom-tag" rel="alternate"/><published>2008-10-17T14:01:49+00:00</published><updated>2008-10-17T14:01:49+00:00</updated><id>https://simonwillison.net/2008/Oct/17/fowa/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://highearthorbit.com/fowa-london-beyond-googlemaps/"&gt;FOWA London - Beyond GoogleMaps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Turner’s talk at FOWA was the most information dense presentation I’ve ever seen, and discussed a huge number of cool geo projects that I’d never previously heard of. Andrew links to the full slides and video, well worth a watch.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-turner"&gt;andrew-turner&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/fowa2008"&gt;fowa2008&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-turner"/><category term="fowa2008"/><category term="geospatial"/><category term="google-maps"/><category term="maps"/></entry><entry><title>Places to see in London (for geeks)</title><link href="https://simonwillison.net/2008/Oct/8/london/#atom-tag" rel="alternate"/><published>2008-10-08T14:54:02+00:00</published><updated>2008-10-08T14:54:02+00:00</updated><id>https://simonwillison.net/2008/Oct/8/london/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://icanhaz.com/londonguide"&gt;Places to see in London (for geeks)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
My geek-oriented guide to London attractions that you may not hear about otherwise, updated for this year’s overseas FOWA attendees. Suggestions for additions welcome.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/fowa2008"&gt;fowa2008&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geeks"&gt;geeks&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/googlemymaps"&gt;googlemymaps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/london"&gt;london&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;&lt;/p&gt;



</summary><category term="fowa2008"/><category term="geeks"/><category term="googlemymaps"/><category term="london"/><category term="maps"/></entry><entry><title>Ordnance Survey OpenSpace Demo</title><link href="https://simonwillison.net/2008/Jun/9/ordnance/#atom-tag" rel="alternate"/><published>2008-06-09T10:59:40+00:00</published><updated>2008-06-09T10:59:40+00:00</updated><id>https://simonwillison.net/2008/Jun/9/ordnance/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.niallkennedy.com/code/maps/openspace.html"&gt;Ordnance Survey OpenSpace Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Niall Kennedy threw a demo up on his site—the map seems to load a lot faster than Google Maps and the level of detail once you zoom down to street level is really impressive.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://simonwillison.net/2008/Jun/9/os/#c39338"&gt;Niall Kennedy&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/niall-kennedy"&gt;niall-kennedy&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openspace"&gt;openspace&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ordinancesurvey"&gt;ordinancesurvey&lt;/a&gt;&lt;/p&gt;



</summary><category term="maps"/><category term="niall-kennedy"/><category term="openspace"/><category term="ordinancesurvey"/></entry><entry><title>OS OpenSpace from Ordnance Survey</title><link href="https://simonwillison.net/2008/Jun/9/os/#atom-tag" rel="alternate"/><published>2008-06-09T08:30:13+00:00</published><updated>2008-06-09T08:30:13+00:00</updated><id>https://simonwillison.net/2008/Jun/9/os/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://openspace.ordnancesurvey.co.uk/openspace/"&gt;OS OpenSpace from Ordnance Survey&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Ordinance Survey now provide a free JavaScript mapping API for “non-commercial purposes” by “private individuals”. The maps look incredibly detailed, although I can’t find any live API demos on the site (the documentation is illustrated with screenshots).

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://simonwillison.net/2008/Mar/22/wikinear/#c39334"&gt;Phil Wilson&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openspace"&gt;openspace&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ordinancesurvey"&gt;ordinancesurvey&lt;/a&gt;&lt;/p&gt;



</summary><category term="geospatial"/><category term="javascript"/><category term="maps"/><category term="openspace"/><category term="ordinancesurvey"/></entry><entry><title>OSM Super-Strength Export</title><link href="https://simonwillison.net/2008/Apr/22/opengeodata/#atom-tag" rel="alternate"/><published>2008-04-22T09:56:07+00:00</published><updated>2008-04-22T09:56:07+00:00</updated><id>https://simonwillison.net/2008/Apr/22/opengeodata/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.opengeodata.org/?p=290"&gt;OSM Super-Strength Export&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Awesome new feature on OpenStreetMap: you can browse to anywhere on the map, then hit “export” and download a rendered bitmap or vector (PDF and SVG) image of the currently displayed map—and because it’s OSM there’s no watermark and a very liberal usage license.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pdf"&gt;pdf&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/svg"&gt;svg&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vector"&gt;vector&lt;/a&gt;&lt;/p&gt;



</summary><category term="mapping"/><category term="maps"/><category term="openstreetmap"/><category term="pdf"/><category term="svg"/><category term="vector"/></entry><entry><title>KML: A new standard for sharing maps</title><link href="https://simonwillison.net/2008/Apr/14/kml/#atom-tag" rel="alternate"/><published>2008-04-14T18:36:39+00:00</published><updated>2008-04-14T18:36:39+00:00</updated><id>https://simonwillison.net/2008/Apr/14/kml/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://google-latlong.blogspot.com/2008/04/kml-new-standard-for-sharing-maps.html"&gt;KML: A new standard for sharing maps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Google’s KML format, which is already supported by both Microsoft and Yahoo!’s map software, has been accepted under the wing of the Open Geospatial Consortium and is now an international standard.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kml"&gt;kml&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ogc"&gt;ogc&lt;/a&gt;&lt;/p&gt;



</summary><category term="google"/><category term="google-maps"/><category term="kml"/><category term="mapping"/><category term="maps"/><category term="ogc"/></entry><entry><title>A List Apart: Issue 256</title><link href="https://simonwillison.net/2008/Apr/9/ala/#atom-tag" rel="alternate"/><published>2008-04-09T12:21:30+00:00</published><updated>2008-04-09T12:21:30+00:00</updated><id>https://simonwillison.net/2008/Apr/9/ala/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.alistapart.com/issues/256"&gt;A List Apart: Issue 256&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The EveryBlock issue. Paul Smith on EveryBlock’s tasty custom maps, and Wilson Miner on EveryBlock’s tasty accessible data charts.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/a-list-apart"&gt;a-list-apart&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/everyblock"&gt;everyblock&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/paul-smith"&gt;paul-smith&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/wilson-miner"&gt;wilson-miner&lt;/a&gt;&lt;/p&gt;



</summary><category term="a-list-apart"/><category term="everyblock"/><category term="maps"/><category term="paul-smith"/><category term="wilson-miner"/></entry><entry><title>London Connections</title><link href="https://simonwillison.net/2008/Apr/2/london/#atom-tag" rel="alternate"/><published>2008-04-02T20:53:12+00:00</published><updated>2008-04-02T20:53:12+00:00</updated><id>https://simonwillison.net/2008/Apr/2/london/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://londonconnections.blogspot.com/"&gt;London Connections&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Marvellously obsessive blog about the vagaries of London transport, including some really nice custom created maps. I love detailed maps of tube stations; anyone know a good place to find them?


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/london"&gt;london&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/londonconnections"&gt;londonconnections&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/transport"&gt;transport&lt;/a&gt;&lt;/p&gt;



</summary><category term="london"/><category term="londonconnections"/><category term="mapping"/><category term="maps"/><category term="transport"/></entry><entry><title>Google Maps Clusterer</title><link href="https://simonwillison.net/2008/Jan/28/javascript/#atom-tag" rel="alternate"/><published>2008-01-28T15:07:31+00:00</published><updated>2008-01-28T15:07:31+00:00</updated><id>https://simonwillison.net/2008/Jan/28/javascript/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.acme.com/javascript/#Clusterer"&gt;Google Maps Clusterer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I’ve looked at a few clustering libraries for Google Maps, but this one seems to have the nicest API.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/clustering"&gt;clustering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;&lt;/p&gt;



</summary><category term="clustering"/><category term="google-maps"/><category term="maps"/></entry><entry><title>Information Freeway</title><link href="https://simonwillison.net/2007/Oct/14/osm/#atom-tag" rel="alternate"/><published>2007-10-14T23:58:09+00:00</published><updated>2007-10-14T23:58:09+00:00</updated><id>https://simonwillison.net/2007/Oct/14/osm/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.informationfreeway.org/"&gt;Information Freeway&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Really lovely interface to Open Street Map, sadly suffering from a horribly vague name and almost no publicity at all.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://simonwillison.net/2007/Oct/12/latlon/#c37500"&gt;Andy Allan&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/mapping"&gt;mapping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openstreetmap"&gt;openstreetmap&lt;/a&gt;&lt;/p&gt;



</summary><category term="mapping"/><category term="maps"/><category term="openstreetmap"/></entry><entry><title>Get Lat Lon</title><link href="https://simonwillison.net/2007/Oct/12/latlon/#atom-tag" rel="alternate"/><published>2007-10-12T14:14:19+00:00</published><updated>2007-10-12T14:14:19+00:00</updated><id>https://simonwillison.net/2007/Oct/12/latlon/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.getlatlon.com/"&gt;Get Lat Lon&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I finally got fed up of hunting around for simple latitude/longitude tools when messing around with mapping APIs, so I built my own with a memorable URL. I plan to add new features as and when I need them.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/getlatlon"&gt;getlatlon&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-maps"&gt;google-maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/latitude"&gt;latitude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/latlon"&gt;latlon&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/longitude"&gt;longitude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/maps"&gt;maps&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/negeography"&gt;negeography&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;&lt;/p&gt;



</summary><category term="getlatlon"/><category term="google-maps"/><category term="latitude"/><category term="latlon"/><category term="longitude"/><category term="maps"/><category term="negeography"/><category term="projects"/></entry></feed>