2023-02-09
Set up maps on your website
If you are like me you may needed to add a map on a website. This seems not so trivial to do!
First of all you need to pick a map source:
- Google Maps
- OpenStreetMap (OSM)
- Apple Maps
- Others
As of recently I am trying to use Google's products less and less. So let's skip that option.
OSM is big:
on 2023-02-01, the plain OSM XML variant takes over 1696.6 GB when uncompressed from the 123.4 GB bzip2-compressed or 67.3 GB PBF-compressed downloaded data file
Ref: https://wiki.openstreetmap.org/wiki/Planet.osm
Now that you picked the source of your map how do you display it to the user?
Raster tiles🔗
Raster tiles are pre-rendered images of a certain location.

If you want to display a map without any dependencies you can just load the needed tiles and join them together.



Sample libraries🔗
- Leaflet js uses raster tiles.
Vector tiles🔗
If you want to be modern and cool and can take a look at vector tiles. Vector tiles are tiles that still need to be rendered.
When using raster tiles, if you want to change the map style, you have to use a different set of tiles (often called a tile layer). Whereas with vector tiles, you can simply apply a different style to the same tiles (since the rendering happens on the client-side).
Seems like OSM doesn't support this yet so we will use another tiling provider for examples. Let's pick a server from this list.
Can we fetch the exact same area but as vector? I have queries both MapTiler and Qwant. Vector tiles are returned in PBF format (protobuf). Let's explore its contents:
$ nix-shell -p osmium-tool
$ osmium fileinfo 9484.pbf
File:
Name: 9484.pbf
Format: PBF
Compression: none
Size: 12483
PBF error: invalid BlobHeader size (> max_blob_header_size)
Oops... Apparently, osmium expects a complete map, like liechtenstein-latest.osm.pbf.
In our case we just need to parse a single vector tile in mapbox format. OK let's try to read with Deno using JS libraries:
;
;
;
;
;
tile;
Trimmed result:
VectorTile

Sample libraries🔗
Raster vs Vector🔗
Raster | Vector | |
---|---|---|
Simple | ✓ | ⨯ |
Size | ⨯ | ✓ |
Customizable | Need server to render differently | Change labels, styles when rendering on the client |
Client support | ✓ | ~ |
Tiling server | Can use OSM for low volume queries | Need to use a third-party server1 |
You can also set up your own server. First, download the data from OSM. Second, convert OSM map data to vector tiles. Finally, host your tiles.
Apple maps🔗
Why Apple maps? I have an Apple Developer account so I do get this kind of for free.
MapKit JS provides a free daily limit of 250,000 map views and 25,000 service calls per Apple Developer Program membership.
// Import TypeScript type definition for use in Deno
;
;
// Load and init the map
;
"src",
"https://cdn.apple-mapkit.com/mk/5.x.x/mapkit.core.js",
;
// This attribute instructs the browser to connect to the MapKit JS CDN using anonymous credentials mode.
// This improves performance by allowing subsequent MapKit JS network requests to reuse the same HTTP/2 connection.
script.crossOrigin = "anonymous";
script.dataset.libraries = "map,annotations";
script.dataset.callback = "initMapKit";
script;
window.initMapKit =;
There is a bit of a catch. Apple Maps in some areas has a lot less details.



What to choose?🔗
It is up to you!
If you already have an Apple developer account then you may use Apple's maps. They provide a high daily limit for free. If you website is low traffic then you can use OSM's raster images directly. If you want maps to look a tiny bit better then you will need to pick a third party provider like https://www.maptiler.com/.
Google maps is also an option if you are into that sort of thing.