Tile Providers¶
Yoro works with any map tile provider. This guide shows how to configure different tile sources for various use cases.
Quick Reference¶
Best for general use. Free, no API key needed.
Free satellite imagery. Great for verifying parcel boundaries.
Free topographic map. Useful for altitude and terrain context.
Complete Example: Multi-Layer Map¶
A full example with layer switching — ideal for field applications:
<!DOCTYPE html>
<html>
<head>
<title>Yoro Multi-Layer Map</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css" />
<style>
body { margin: 0; }
#map { height: 100vh; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
<script>
// Base layers
const osm = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{ attribution: '© OSM', maxZoom: 19 }
);
const satellite = L.tileLayer(
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
{ attribution: '© Esri', maxZoom: 18 }
);
const topo = L.tileLayer(
'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
{ attribution: '© OpenTopoMap', maxZoom: 17 }
);
const light = L.tileLayer(
'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',
{ attribution: '© CARTO', maxZoom: 20 }
);
// Initialize with OSM
const map = L.map('map', {
center: [7.5, -5.5],
zoom: 7,
layers: [osm],
});
// Layer control
L.control.layers({
'OpenStreetMap': osm,
'Satellite': satellite,
'Topographic': topo,
'Light': light,
}).addTo(map);
</script>
</body>
</html>
Choosing the Right Tiles¶
| Use Case | Provider | Why |
|---|---|---|
| General navigation | OpenStreetMap | Free, detailed roads/buildings |
| Parcel verification | ESRI Satellite | See actual land, trees, buildings |
| Terrain analysis | OpenTopoMap | Elevation contours, slopes |
| Data visualization | CartoDB Positron | Clean background for Yoro grid |
| Offline/field use | MBTiles | Pre-downloaded, no internet needed |
Offline Tiles (MBTiles)¶
For field agents without internet connectivity, pre-download tiles as MBTiles:
# In your Django app, serve offline tiles
# Store .mbtiles files and serve via a tile proxy view
from django.http import HttpResponse
import sqlite3
def offline_tile(request, z, x, y):
"""Serve tiles from a local .mbtiles file."""
y_tms = (1 << z) - 1 - y # TMS to XYZ conversion
conn = sqlite3.connect('/path/to/region.mbtiles')
cursor = conn.execute(
'SELECT tile_data FROM tiles WHERE zoom_level=? AND tile_column=? AND tile_row=?',
(z, x, y_tms)
)
row = cursor.fetchone()
conn.close()
if row:
return HttpResponse(row[0], content_type='image/png')
return HttpResponse(status=404)
Then in Leaflet:
const offlineTiles = L.tileLayer('/tiles/{z}/{x}/{y}.png', {
maxZoom: 16,
attribution: 'Offline tiles',
});
Combining Yoro with offline maps
Yoro codes are computed purely from math — they work offline without any API call. Combined with pre-downloaded MBTiles, field agents can use the full addressing system with zero connectivity.
Satellite Imagery for EUDR¶
For EUDR (EU Deforestation Regulation) compliance, satellite imagery is critical to verify that parcels are not on deforested land:
// NICFI Planet basemaps (free for tropical forests, requires signup)
// https://www.planet.com/nicfi/
const nicfi = L.tileLayer(
'https://tiles.planet.com/basemaps/v1/planet-tiles/planet_medres_normalized_analytic_{period}_mosaic/gmap/{z}/{x}/{y}.png?api_key={key}',
{
attribution: '© Planet Labs',
maxZoom: 17,
period: '2024-01', // Monthly mosaics available
key: 'YOUR_NICFI_API_KEY',
}
);
This lets you overlay Yoro codes on satellite imagery to visually verify each parcel's forest status.