Maps on Blossom and Nostr

Demo project to serve map tiles from blossom blobs.
Maps on Blossom and Nostr

GM,

This is what i hacked together at the SEC. As it turns out, through the magic of HTTP range requests, we can serve map tiles from blossom.

Check out the demo at earthly.city:

image

The base map of earthly is hosted on satellite earth and I’m working on bringing it to blossom.earthly.city.

If you click on Globe icon on the left side of the toolbar you can create and deploy small throw away websites, by dragging a rect, with map chunks down to the max z-level. Im using ContextVM and nsyte to deploy it. Here is an example of such a map app: https://npub1c2rftpr5h83wjm4w6vxt0srassxv8fag5zc7zuh79p8d55uf8v0sltpz7j.nsite.earthly.city/

Try deploying an island or something small because otherwise the processing might take too long and the MCP client might time out.

You can already use this for maps that don’t require full zoom: https://cdn.satellite.earth/8995fe122d595244c7051650b579e9c0b221549f9f4f4e055ee204779695a4aa.pmtiles

Its a 1.5GB file that brings you down to municipality level. This file format/library is responsible for the magic: protomaps.com

If you have a web app you can use this snippet:

import * as PMTiles from 'pmtiles'
import ml from 'maplibre-gl'

useEffect(() => {
	const protocol = new PMTiles.Protocol()
	ml.addProtocol('pmtiles', protocol.tile)
  
	return () => {
		ml.removeProtocol('pmtiles')
	}
}, [])

const mapSourceUrl = 'https://cdn.satellite.earth/8995fe122d595244c7051650b579e9c0b221549f9f4f4e055ee204779695a4aa.pmtiles'

const map = new ml.Map({
	container: mapRef.current,
	zoom: 4,
	style: {
		glyphs: 'https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf',
		sprite: 'https://protomaps.github.io/basemaps-assets/sprites/v4/light',
		version: 8,
		sources: {
			osm: {
				type: 'vector',
				url: `pmtiles://${mapSourceUrl}`,
			},
		},
		layers: mapLayers,
	},

})

…eventually map styles should be on nostr too.

Hosting map tiles from blossom has a caveat: a full planet file has 120GB and the servers that i tried don’t seem to be able to digest range requests to such files. Naturally the next step would be splitting up tile sets in digestible files.

I’ve implemented a demo of a composite map at https://www.earthly.city/map/combined. My VPS provider is having issues so the map loading can be very slow. Check back later if you have issues seeing the map.

Right now the ‘announcement’ is a set of a map quadrants corresponding to bounding boxes:

// Demo PMTiles quadrants for Germany/Austria/Switzerland region

export const DEMO_QUADRANT_ARCHIVES: Archive[] = [
	{
		role: 'vector-base',
		hash: 'c293a371995dce686d4a97fa08d14cf1b1e299dfda13354780d7d810424b3af7', // SW quadrant
		zmin: 0,
		zmax: 14,
		bbox: [8.221593, 46.3829795, 9.2614745, 47.422861], // SW bounds
	},
	{
		role: 'vector-base',
		hash: 'c8855bea14ca5b17a81b936c0ae9a398e87ae723ed56af5123119d22ac5c108d', // NE quadrant
		zmin: 0,
		zmax: 14,
		bbox: [9.2614745, 47.422861, 10.301356, 48.4627425], // NE bounds
	},
...
]

Implemented properly if would be a set of geohashes mapped to blossom links:

export const DEMO_QUADRANT_ARCHIVES: Archive[] = [
	{
		role: 'vector-base',
		hash: 'c293a371995dce686d4a97fa08d14cf1b1e299dfda13354780d7d810424b3af7', // SW quadrant
		zmin: 0,
		zmax: 14,
		geohash: '21m', // SW bounds
	},
	{
		role: 'vector-base',
		hash: 'c8855bea14ca5b17a81b936c0ae9a398e87ae723ed56af5123119d22ac5c108d', // NE quadrant
		zmin: 0,
		zmax: 14,
		geohash: '21k', // NE bounds
	},
...
]

This way it could be viable to construct planet.pmtiles fully from a set of 500 - 700Mb files.

sauce: nostr://@8658…qrsg/relay.ngit.dev/earthly-city


Write a comment
2 sat
Zap
42 sat
2 sat

this is what we need, people hosting their own maps and overlaying with their pins outside of google 🚀

Zap

🦍 from La Crypta

Zap

Yaki messed up the video:

Reply to Schlaus Kwab…