Published
Edited
Jul 1, 2020
Insert cell
Insert cell
Insert cell
Insert cell
projection = d3.geoMercator()
.center([-73.9888682,40.6916651])
.scale((1 << 24) / (2 * Math.PI))
.translate([width / 2, height / 2])
.precision(0)
Insert cell
Insert cell
tile = d3.tile()
.size([width, height])
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]))
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`);
return d;
}))
Insert cell
Insert cell
roads = tiles
.map(t => t.data.roads.features
.filter(f => f.properties.kind != "ferry" && f.properties.kind != "rail" && f.properties.kind != "highway"))
.filter(m => m.length > 0)
Insert cell
Insert cell
multilines = roads.map(r=> r.map(l => { if (l.geometry.type == "MultiLineString"){ return l.geometry.coordinates.map(fm => turf.lineString(fm, {id: l.properties.id})).flat()} else { return l}}).flat()).flat()
Insert cell
longLines = idsPrime.map(i => multilines.filter(m => m.properties.id == i).map(a => turf.combine(a))).flat().map(a => a.features.map(f=> f.geometry.coordinates.map(fm => turf.lineString(fm))).flat()).flat()
Insert cell
Insert cell
points = longLines.map(m => longLines.map(l => turf.lineIntersect(l, m)).filter(f => f.features.length > 0)).flat()
Insert cell
Insert cell
test = function(){
let index = []
longLines.forEach(function(r){
// find roads that cross road
let crosses = longLines.filter(m => turf.booleanCrosses(m, r))
//if a road does not cross any other road (apparently a thing??), push to array anyway
if (crosses.length == 0){
r.properties.length = turf.length(r)
index.push(r)
// split all roads that do have crossing roads at intersection
} else {
let feat = crosses.map(s => turf.lineSplit(r,s))
let t = feat.map(f => f.features.map((m) => {
m.properties.id = r.properties.id;
m.properties.name = r.properties.name;
m.properties.length = turf.length(m);
return m })).flat()
index.push(t)
}
})
//this is lazy but for now: using sort to see shortest paths on map
return index.flat().sort((a,b) => {return turf.length(a) - turf.length(b)}).reverse()}();
Insert cell
Insert cell
Insert cell
removeLongestLine = function(){
let arr = [];
idsPrime.forEach(i => {
let demo = test.filter(t => t.properties.id == i)
if (demo.length < 2){arr.push(demo)}
let remove = demo.filter(m => turf.length(m)!= Math.max(...demo.map(m => turf.length(m))))
arr.push(remove)
})
return arr.flat()
}()
Insert cell
Insert cell
crossHenry = henry.map(h => multilines.filter(l => turf.booleanCrosses(h,l) == true).map(m => turf.lineSplit(h, m)).map(a => a.features).flat()).flat()
Insert cell
henry = roads.flat().filter(f => f.properties.name == "Henry St.")
Insert cell
joralemon = roads.flat().filter(f => f.properties.name == "Joralemon St.")
Insert cell
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>
`)}

${longLines.map(t => svg `<path stroke = "${newcolors[Math.floor(Math.random()*d3colors.length)]}" fill = "none"stroke-width="2" d="${path(t)}"></path>`)}

${test.map(t => svg `<path stroke = "${d3colors[Math.floor(Math.random()*d3colors.length)]}" fill = "none"stroke-width="3" d="${path(t)}"></path>`)}


</svg>`
Insert cell
Insert cell
Insert cell
Insert cell
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