Published
Edited
Nov 15, 2019
2 stars
Insert cell
Insert cell
Insert cell
L = require('leaflet@1.2.0')
Insert cell
html`<link href='${resolve('leaflet@1.2.0/dist/leaflet.css')}' rel='stylesheet' />`
Insert cell
Insert cell
map = {
// You'll often see Leaflet examples initializing a map like L.map('map'),
// which tells the library to look for a div with the id 'map' on the page.
// In Observable, we instead create a div from scratch in this cell (called "map")
let container = DOM.element('div', { style: `width:${width}px;height:${width/1.6}px` });
// This component utilizes "yield" which pauses the execution of this code block
// returns the value of container back to the notebook which allows the
// div to be placed on the page. This is important, because Leaflet uses
// the div's .offsetWidth and .offsetHeight (used to get current size of the div)
// to size the map. If I were to only return the container at the end of this method,
// Leaflet might get the wrong idea about the map's size.
yield container;
// Now we create a map object and add a layer to it.
let map = L.map(container).setView([49.2527, -123.1207], 11.5); // initializes the map, sets zoom & coordinates
let osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map); //This adds the tile layer to the map. The map dynamically loads tiles based on current view the experience smooth and seamless. Make sure to add attribution to your map.
}
Insert cell
Insert cell
VanAreas = FileAttachment("VancouverAreaSize.json").json()
Insert cell
VanAreasMap = {

let container = DOM.element('div', { style: `width:${width}px;height:${width/1.6}px` });
yield container;
let map = L.map(container);
let osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
let VanAreasLayer = L.geoJson(VanAreas, { //instantiates a new geoJson layer using built in geoJson handling
weight: 2, //Attributes of polygons including the weight of boundaries and colors of map.
color: "#488",
}).bindPopup(function (Layer) { //binds a popup when clicking on each polygon to access underlying data
return Layer.feature.properties.NAME;
}).addTo(map); //Adds the layer to the map.
map.fitBounds(VanAreasLayer.getBounds()); //finds bounds of polygon and automatically gets map view to fit (useful for interaction and not having to 'cook' the map zoom and coordinates as in map instantiation
}
Insert cell
Insert cell
D3VanAreasMap = {

let container = DOM.element('div', { style: `width:${width}px;height:${width/1.6}px` });
yield container;

let map = L.map(container).setView([49.2527, -123.1207], 11.5);
let osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
//initialize svg to add to map
L.svg().addTo(map)
//Create selection using D3
const overlay = d3.select(map.getPanes().overlayPane)
const svg = overlay.select('svg')
// create a group that is hidden during zooming
const g = svg.append('g').attr('class', 'leaflet-zoom-hide')
// convert x y coordinates to current coordinates in leaflet
const projectPoint = function(x, y) {
const point = map.latLngToLayerPoint(new L.LatLng(y, x))
this.stream.point(point.x, point.y)
}
const random255 = () => Math.round(Math.random() * 255)
const getColor = () => `rgb(${random255()},${random255()},${random255()})`
// Projection
const projection = d3.geoTransform({point: projectPoint})
// function to create attributes of path
const pathCreator = d3.geoPath().projection(projection)
const countryPaths = g.selectAll('path')
.data(VanAreas.features)
.enter()
.append('path')
.attr('opacity', 0.3)
// .attr('stroke', 'black')
.attr('stroke', getColor)
.attr('stroke-width', 2.5)
// Function to place svg based on zoom
const onZoom = () => countryPaths.attr('d', pathCreator)
// initialize positioning
onZoom()
// reset whenever map is moved
map.on('zoomend', onZoom)
}
Insert cell
Insert cell
md `NOTE: check these sites on how to make a selectable layer in d3 on top of Leaflet. <br>
<ul>
<li>https://www.codementor.io/higheredbob/d3-v3-animate-paths-and-points-twieb5blx
<li>http://zevross.com/blog/2014/09/30/use-the-amazing-d3-library-to-animate-a-path-on-a-leaflet-map/ (this may be old)
</ul>`
Insert cell
areaSelect = require('leaflet-area-select')
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
heatLayer = L, require('leaflet.heat').catch(() => L.heatLayer)
Insert cell
VegaLite = require('vega-embed@6')
Insert cell
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