Code Examples
Ready-to-use code snippets for integrating CCA map tiles into your application. All examples use the tile server at maps.datasourceapi.com.
https://maps.datasourceapi.com/api/v1/tiles/{layerId}/{z}/{x}/{y}.{ext}.
You can also use the built-in styles at /api/v1/styles/light.json and /api/v1/styles/dark.json.
MapLibre GL JS
MapLibre GL JS is the recommended client for vector tiles. It renders MVT tiles on the GPU for smooth, interactive maps with full styling control.
Minimal example using the built-in light style. Just include MapLibre GL JS and point to our style endpoint.
<!DOCTYPE html>
<html>
<head>
<link href="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css" rel="stylesheet">
<style>
#map { width: 100%; height: 100vh; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js"></script>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://maps.datasourceapi.com/api/v1/styles/light.json',
center: [-98.5, 39.8], // Center of US
zoom: 4,
});
map.addControl(new maplibregl.NavigationControl());
</script>
</body>
</html>
Toggle between light and dark built-in styles. The server provides complete MapLibre style JSON with all layer definitions.
const BASE = 'https://maps.datasourceapi.com/api/v1';
const map = new maplibregl.Map({
container: 'map',
style: `${BASE}/styles/light.json`,
center: [0, 20],
zoom: 2,
});
// Toggle between light and dark
let isDark = false;
document.getElementById('toggle-theme').addEventListener('click', () => {
isDark = !isDark;
map.setStyle(`${BASE}/styles/${isDark ? 'dark' : 'light'}.json`);
});
Add 3D terrain using the Terrain RGB tiles. Requires MapLibre GL JS v3+ with terrain support.
const map = new maplibregl.Map({
container: 'map',
style: 'https://maps.datasourceapi.com/api/v1/styles/light.json',
center: [-112.1, 36.1], // Grand Canyon
zoom: 12,
pitch: 60,
bearing: -17,
});
map.on('load', () => {
// Add terrain RGB source
map.addSource('terrain-rgb', {
type: 'raster-dem',
url: 'https://maps.datasourceapi.com/api/v1/layers/terrain-rgb/tilejson.json',
encoding: 'terrarium',
tileSize: 256,
});
// Enable 3D terrain
map.setTerrain({
source: 'terrain-rgb',
exaggeration: 1.5,
});
// Optional: Add hillshade layer
map.addSource('hillshade-source', {
type: 'raster-dem',
url: 'https://maps.datasourceapi.com/api/v1/layers/terrain-rgb/tilejson.json',
encoding: 'terrarium',
tileSize: 256,
});
map.addLayer({
id: 'hillshade',
type: 'hillshade',
source: 'hillshade-source',
paint: {
'hillshade-exaggeration': 0.5,
'hillshade-shadow-color': '#473B24',
},
}, 'water'); // Insert below water layer
});
Add individual overlay layers (buildings, transportation, places) on top of the basemap.
const BASE = 'https://maps.datasourceapi.com/api/v1';
const map = new maplibregl.Map({
container: 'map',
style: `${BASE}/styles/light.json`,
center: [-122.42, 37.78], // San Francisco
zoom: 14,
});
map.on('load', () => {
// Add Overture Buildings source
map.addSource('overture-buildings', {
type: 'vector',
url: `${BASE}/layers/overture-buildings/tilejson.json`,
});
// 3D extruded buildings
map.addLayer({
id: 'buildings-3d',
type: 'fill-extrusion',
source: 'overture-buildings',
'source-layer': 'buildings',
minzoom: 13,
paint: {
'fill-extrusion-color': '#aaa',
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-base': 0,
'fill-extrusion-opacity': 0.6,
},
});
// Add Overture Places source
map.addSource('overture-places', {
type: 'vector',
url: `${BASE}/layers/overture-places/tilejson.json`,
});
// Show place markers
map.addLayer({
id: 'places-markers',
type: 'circle',
source: 'overture-places',
'source-layer': 'places',
minzoom: 12,
paint: {
'circle-radius': 4,
'circle-color': '#e74c3c',
'circle-stroke-width': 1,
'circle-stroke-color': '#fff',
},
});
});
Leaflet
Leaflet is lightweight and works great for raster tiles. For vector tiles, use the maplibre-gl-leaflet plugin or leaflet.vectorgrid.
Use the terrain RGB tiles as a raster layer in Leaflet. For vector basemap tiles, see the vector example.
maplibre-gl-leaflet plugin below.
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
<script>
const map = L.map('map').setView([39.8, -98.5], 4);
// Terrain RGB as a raster layer (useful for visualization)
L.tileLayer(
'https://maps.datasourceapi.com/api/v1/tiles/terrain-rgb/{z}/{x}/{y}.png',
{
maxZoom: 15,
attribution: 'Terrain: AWS Open Data / Mapzen',
}
).addTo(map);
</script>
Use MapLibre GL JS as a Leaflet plugin to render vector tiles within a Leaflet map.
<!-- Include both Leaflet and MapLibre GL -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css">
<link href="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css" rel="stylesheet">
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
<script src="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.0.22/leaflet-maplibre-gl.js"></script>
<script>
const map = L.map('map').setView([39.8, -98.5], 4);
L.maplibreGL({
style: 'https://maps.datasourceapi.com/api/v1/styles/light.json',
}).addTo(map);
</script>
OpenLayers
OpenLayers natively supports both vector tiles (MVT) and raster tiles.
Load vector tiles directly in OpenLayers using the MVT format.
import Map from 'ol/Map';
import View from 'ol/View';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import MVT from 'ol/format/MVT';
import { fromLonLat } from 'ol/proj';
const map = new Map({
target: 'map',
layers: [
new VectorTileLayer({
source: new VectorTileSource({
format: new MVT(),
url: 'https://maps.datasourceapi.com/api/v1/tiles/osm-planet/{z}/{x}/{y}.pbf',
maxZoom: 15,
attributions: '© OpenStreetMap contributors',
}),
}),
],
view: new View({
center: fromLonLat([-98.5, 39.8]),
zoom: 4,
}),
});
Load terrain RGB tiles as a raster source.
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import { fromLonLat } from 'ol/proj';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://maps.datasourceapi.com/api/v1/tiles/terrain-rgb/{z}/{x}/{y}.png',
maxZoom: 15,
attributions: 'Terrain: AWS Open Data / Mapzen',
}),
}),
],
view: new View({
center: fromLonLat([-98.5, 39.8]),
zoom: 4,
}),
});
API Usage
Direct API usage for fetching layer metadata, TileJSON, and tiles programmatically.
const BASE = 'https://maps.datasourceapi.com/api/v1';
// List all layers
const layers = await fetch(`${BASE}/layers`).then(r => r.json());
console.log(layers.data.layers);
// Filter by category
const overlays = await fetch(`${BASE}/layers?category=overlay`).then(r => r.json());
// Get layer detail
const layer = await fetch(`${BASE}/layers/osm-planet`).then(r => r.json());
console.log(layer.data.tiles_url);
// Get TileJSON (standard format for tile metadata)
const tilejson = await fetch(`${BASE}/layers/osm-planet/tilejson.json`).then(r => r.json());
console.log(tilejson.tiles); // Array of tile URL templates
// Fetch a single tile
const tile = await fetch(`${BASE}/tiles/osm-planet/12/1234/567.pbf`);
console.log(tile.headers.get('content-type')); // application/x-protobuf
console.log(tile.headers.get('x-cache')); // HIT or MISS
# List all layers
curl -s https://maps.datasourceapi.com/api/v1/layers | jq '.data.layers[].name'
# Get TileJSON for OSM planet
curl -s https://maps.datasourceapi.com/api/v1/layers/osm-planet/tilejson.json | jq
# Download a single tile
curl -o tile.pbf https://maps.datasourceapi.com/api/v1/tiles/osm-planet/0/0/0.pbf
# Check cache status
curl -sI https://maps.datasourceapi.com/api/v1/tiles/osm-planet/2/1/1.pbf | grep -i 'x-cache'
# Get light style JSON
curl -s https://maps.datasourceapi.com/api/v1/styles/light.json | jq '.name'
# Health check
curl -s https://maps.datasourceapi.com/health | jq
# Server stats
curl -s https://maps.datasourceapi.com/api/v1/stats | jq
import requests
BASE = "https://maps.datasourceapi.com/api/v1"
# List all layers
resp = requests.get(f"{BASE}/layers")
layers = resp.json()["data"]["layers"]
for layer in layers:
print(f"{layer['id']:30s} {layer['category']:12s} {layer['tileType']}")
# Get TileJSON
tilejson = requests.get(f"{BASE}/layers/osm-planet/tilejson.json").json()
print(f"Tile URL: {tilejson['tiles'][0]}")
print(f"Zoom range: {tilejson['minzoom']}-{tilejson['maxzoom']}")
# Download a tile
tile = requests.get(f"{BASE}/tiles/osm-planet/0/0/0.pbf")
print(f"Status: {tile.status_code}, Size: {len(tile.content)} bytes")
print(f"Cache: {tile.headers.get('x-cache', 'unknown')}")
React / Next.js
Using MapLibre GL JS in a React application with the react-map-gl library.
import Map from 'react-map-gl/maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';
function MyMap() {
return (
<Map
initialViewState={{
longitude: -98.5,
latitude: 39.8,
zoom: 4,
}}
style={{ width: '100%', height: '100vh' }}
mapStyle="https://maps.datasourceapi.com/api/v1/styles/light.json"
/>
);
}
export default MyMap;