Published
Edited
Apr 21, 2020
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mutable tileMask=''
Insert cell
mutable activeTileUrl = ''
Insert cell
Insert cell
Insert cell
layers=[{
default : {
lines : { strokeStyle : 'gray', lineWidth : 1, lineJoin : 'round', lineCap : 'round' },
polygons : { strokeStyle : 'rgba(0,0,255,0.1)', fillStyle : 'rgba(0,0,255,0.1)', lineWidth : 1, lineJoin : 'round', lineCap : 'round' },
points : { strokeStyle : 'red', fillStyle : 'rgba(255,0,0,0.3)', lineWidth : 1, radius : 5 },
}
}]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mapConfig=({
minZoom : 1,
maxZoom: 18,
zoom: 12,
center : [2.35, 48.85],
// tilesUrl : 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
tilesUrl : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
// tilesUrl : 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}@2x.png'
})
Insert cell
function newTilesSelector({ container, onTileSelect = (()=>{}), ...mapConfig }) {

const map = newLeafletMap(container, mapConfig);

const MyGridLayer = L.GridLayer.extend({

_selectTile(info) {
if (this._selection) {
this._selection.remove();
this._selection = null;
}

info = info || this._selectedTileInfo;
if (!info) return ;
const { x, y, z } = info || {};
this._selectedTileInfo = { x, y, z };

const bounds = L.latLngBounds([
[ tileUtils.tile2lat(y, z), tileUtils.tile2long(x+1, z)],
[ tileUtils.tile2lat(y+1, z), tileUtils.tile2long(x, z)]
]);
this._selection = L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(this._map);
},

getEvents: function (...args) {
const events = L.GridLayer.prototype.getEvents.apply(this, args);
return {
...events,
click(e){
const size = this.getTileSize();
const map = this._map;
const zoom = map.getZoom();
const pixelPoint = map.project(e.latlng, zoom).floor();
const coords = pixelPoint.unscaleBy(size).floor();
const tileInfo = { ...coords, z : zoom };
this._selectTile(tileInfo);
this.fire('selecttile', tileInfo);
}
};
},
createTile: function(coords){
const zoom = map.getZoom();
const size = this.getTileSize();
const style = {
width : `${size.x}px`,
height : `${size.y}px`,
// cursor: 'pointer !important',
border : `2px solid rgba(255, 0, 0, 0.3)`,
'font-size' : '1.5em',
}
const tile = L.DomUtil.create('div');
for (const [key, value] of Object.entries(style)) {
tile.style[key] = value;
}
tile.innerHTML = `[${zoom} : ${coords.x} : ${coords.y}]`;
return tile;
}
});

const grid = new MyGridLayer({});
grid
.addTo(map)
.on('selecttile', ({x,y,z}) => onTileSelect({ x, y, z }))
.bringToFront();
return map;
}
Insert cell
Insert cell
L = {
const L = await require('leaflet');
L.cssUrl = resolve('leaflet/dist/leaflet.css');
document.head.appendChild(html`<link href='${L.cssUrl}' rel='stylesheet' />`);
return L;
}
Insert cell
tileUtils={
// See https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
function long2tile(lon,zoom) { return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
function lat2tile(lat,zoom) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
// Inverse process:
function tile2long(x,z) { return (x/Math.pow(2,z)*360-180); }
function tile2lat(y,z) {
var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
}
return {
long2tile,
lat2tile,
tile2long,
tile2lat
}
}
Insert cell
d3 = require('d3@5')
Insert cell
import { newTileContext, drawTile } from "@kotelnikov/mapbox-vector-tiles-rendering"
Insert cell
import { pbftile } from "@kotelnikov/mapbox-vector-tiles-rendering"
Insert cell
import {form} from "@mbostock/form-input"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more