Published
Edited
Jun 3, 2020
2 forks
1 star
Insert cell
Insert cell
md `## Boring stuff setting up tiles`
Insert cell
Insert cell
projection = d3.geoMercator()
.center([-73.9888682,40.6916651]) //https://github.com/d3/d3-geo#projection_center, does what it says on the tin
.scale((1 << 22) / (2 * Math.PI)) // this number is actually 333772.1072150545. Why is it this number? I am assuming this has something to do with projecting from a...circle? Because we're dividing by tau?
//https://github.com/d3/d3-geo#projection_scale
.translate([width / 2, height / 2]) //https://github.com/d3/d3-geo#projection_translate. this feature defaults to translating the center point of your map against a 960x500 area svg? I don't really know why that size. What we have here will translate our map's center to the exact center of the div.
.precision(0) //https://github.com/d3/d3-geo#projection_precision, d3 uses something called adaptive sampling to improve rendering and performance (see https://bl.ocks.org/mbostock/3795544), this definitely falls into "I sort of understand this math, Mike" territory
Insert cell
Insert cell
tile = d3.tile() // based on the following parameters, which tiles will I need to fetch?
.size([width, height]) //it's going to fill this space
.scale(projection.scale() * 2 * Math.PI) // again, I am not 100% sure I know what's going oin
.translate(projection([0, 0])) //don't change anything from the projection
Insert cell
tiles = Promise.all(tile().map(async d => {
d.data = await d3.json(`https://tile.nextzen.org/tilezen/vector/v1/256/all/${d.z}/${d.x}/${d.y}.json?api_key=ztkh_UPOQRyakWKMjH_Bzg`); // map the tiles returned by tile() to the tile API endpoint
return d; // look at the different items that are part of the output data!! so many
}))
Insert cell
Insert cell
roads = tiles.map(t => t.data.roads.features.filter(f => f.properties.kind != "ferry" && f.properties.kind != "rail" )).filter(m => m.length > 0).flat()
Insert cell
md `## for each road in tile, identify overlaps`
Insert cell
test = function(){
let index = []
roads.forEach(function(r){
let obj = {}
obj.name = r.properties.name
obj.points = []
obj.id = r.properties.id
roads.forEach(function(ki,i){
if (ki.properties.id != r.properties.id && ki.properties.name !== undefined && r.properties.name !== undefined){
let int = turf.lineIntersect(r, ki);
if (int.features.length > 0) {
int.features.forEach(function(inter){
if (inter.properties){
inter.properties.intersection = ki.properties.name
inter.properties.ID = ki.properties.id
obj.points.push(inter)
}
})
index.push(obj)
}
}
}
)
})
return index}();
Insert cell
Insert cell
makePoints = function(){
let arr = [];
for (var i = 0; i < test.length; i++){
let obj = test[i].points[0];
arr.push(obj);
}
let geojson = {};
geojson.type = "FeatureCollection";
geojson.features = arr;
return geojson;
}();
Insert cell
md `## Turning the points into Lines`
Insert cell
makeLineString = function(){
let arr = []
for (var i = 0; i < test.length; i++) {
for(var j = 0; j < test[i].points.length; j++){
if (test[i].points[j+1] !== undefined){
let obj = {}
obj.type= "Feature",
obj.properties = {};
obj.properties.path = `${test[i].points[j].properties.intersection} and ${test[i].points[j+1].properties.intersection}`
obj.geometry = {};
obj.geometry.type = "LineString";
obj.geometry.coordinates= [test[i].points[j].geometry.coordinates, test[i].points[j+1].geometry.coordinates]
arr.push(obj)
}
}
} let geojson = {};
geojson.type = "FeatureCollection";
geojson.features = arr;
return geojson;
}()
Insert cell
d3colors = d3.quantize(d3.interpolateHcl("cyan", "hotpink"), 10)
Insert cell
map = svg`<svg viewBox="0 0 ${width} ${height}" style="width:100%;height:auto; id = "map"">
${tiles.map(d => svg`
<path fill="papayawhip" d="${path(d.data.water)}"></path>
<path fill="none" stroke="#ccc" stroke-width="0.75" d="${path(d.data.roads)}"></path
<path fill="green" stroke="pink" stroke-width="1" d=${path(d.data.pois)}"></path>
`)}
${makeLineString.features.map(d => svg `<path stroke = "${d3colors[Math.floor(Math.random()*d3colors.length)]}" stroke-width="3" d="${path(d)}"></path>`)}
${makePoints.features.map(d => svg `<path fill="orange" d="${path(d)}"></path>`)}
</svg>`
Insert cell
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