Public
Edited
Jan 10
Insert cell
Insert cell
Insert cell
function sec(x) {
return 1 / Math.cos(x);
}
Insert cell
function lonlat_to_xyz(lon, lat, z) {
const tile_count = Math.pow(2, z);
const x = (lon + 180) / 360;
const y =
(1 - Math.log(Math.tan(radians(lat)) + sec(radians(lat))) / Math.PI) / 2;
return [Math.floor(tile_count * x), Math.floor(tile_count * y)];
}
Insert cell
function radians(degrees) {
return degrees * (Math.PI / 180);
}
Insert cell
Insert cell
Insert cell
function mercatorToLat(mercatorY) {
return Math.atan(Math.sinh(mercatorY)) * (180 / Math.PI);
}
Insert cell
function y_to_lat_edges(y, z) {
const tile_count = Math.pow(2, z);
const unit = 1 / tile_count;
const relative_y1 = y * unit;
const relative_y2 = relative_y1 + unit;
const lat1 = mercatorToLat(Math.PI * (1 - 2 * relative_y1));
const lat2 = mercatorToLat(Math.PI * (1 - 2 * relative_y2));
return [lat1, lat2];
}
Insert cell
function tile_edges(x, y, z) {
const lon = x_to_lon_edges(x, z);
const lat = y_to_lat_edges(y, z);
return [lon[0], lat[0], lon[1], lat[1]];
}
Insert cell
tile_edges(70424, 43017, 17)
Insert cell
Insert cell
bbox = [52.475411, 13.420666, 52.467127, 13.438159]
Insert cell
zoom = 18
Insert cell
topLeft = lonlat_to_xyz(bbox[1], bbox[0], zoom)
Insert cell
bottomRight = lonlat_to_xyz(bbox[3], bbox[2], zoom)
Insert cell
extent = {
const tl = tile_edges(...topLeft, zoom);
const br = tile_edges(...bottomRight, zoom);
return [br[3], tl[0], tl[1], br[2]];
}
Insert cell
url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
Insert cell
urls = {
const urls = [];
for (let x = topLeft[0]; x <= bottomRight[0]; ++x) {
for (let y = topLeft[1]; y <= bottomRight[1]; ++y) {
urls.push(url.replace("{z}", zoom).replace("{x}", x).replace("{y}", y));
}
}
return urls;
}
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more