Published
Edited
Oct 9, 2022
2 stars
Insert cell
Insert cell
Insert cell
xyz_tiles = xyz(bounds, 10)
Insert cell
map = svg`<svg viewBox="0 0 ${width} ${height}">
<g id="groundwater">
${santaClara.map(
(m) => `<path d =${path(m)} fill="cyan" stroke="cyan" stroke-width="2"/>`
)}
)}
</g>
<g id ='hillshade'>
${classedSplitZ.map(
(h, i) => `<path d ='M${[h.a.x, h.a.y]}L${[h.b.x, h.b.y]}' stroke="black"/>`
)}
</g>
<g id="water">
${geom_water.map((m) => `<path d =${path(m)} fill="gray"/>`)}
)}
</g>

<g id = "plumes">
${zoomed_superfunds.features.map(
(m) => `<path d =${path(m)} fill="lightblue"/>`
)}
</g>
<g id = "roads">
${roads.map(
(m) => `<path d ="${path(m)}" fill="none" stroke-width="0.5" stroke="black"/>`
)}
</g>
<g id = "rwqcb">
${rwqcb.features.map(
(m) =>
`<circle transform ="translate(${projection(m.geometry.coordinates)[0]}, ${
projection(m.geometry.coordinates)[1]
})" r="5" fill="blue" stroke="white" id="${m.properties.name}"></circle>`
)}
</g>
<g id = "rwqcb_open">
${ongoing.map(
(m) =>
`<circle transform ="translate(${projection(m.geometry.coordinates)[0]}, ${
projection(m.geometry.coordinates)[1]
})" r="5" fill="cyan" stroke="white" id="${m.properties.name}"></circle>`
)}
</g>
<g id = "superfund">
${superfunds.features.map(
(m) =>
`<rect transform ="translate(${projection(m.geometry.coordinates)[0]}, ${
projection(m.geometry.coordinates)[1]
}),rotate(45)" width="8" height="8" fill="blue" stroke="white" id="${
m.properties.name
}"></rect>`
)}
</g>
</svg>`
Insert cell
superfunds = FileAttachment("untitled(1).geojson").json()
Insert cell
rewind = turf.rewind(site, { reverse: true })
Insert cell
bounds = [
site.geometry.coordinates[0][0],
site.geometry.coordinates[0][2]
]
Insert cell
site = zoomed_bbox
Insert cell
zoomed_superfunds = FileAttachment("scc_plumes@1.geojson").json()
Insert cell
zoomed_bbox = turf.bboxPolygon(
turf.bbox(
turf.buffer(turf.bboxPolygon(turf.bbox(zoomed_superfunds)), 30, {
unit: "miles"
})
)
)
Insert cell
geojson = FileAttachment("map(12).geojson").json()
Insert cell
ctr = turf.center(site)
Insert cell
turf.center(zoomed_bbox)
Insert cell
projection = d3
.geoMercator()
.center(ctr.geometry.coordinates)
.translate([0, 0])
.fitSize([width, height], rewind)
Insert cell
poly_water = water_nest
.map((e) =>
e.values
.map((v) => {
if (v.geometry.type != "Polygon") {
return turf.flatten(v).features.flat();
} else {
return v;
}
})
.flat()
)
.map((m) => turf.dissolve(turf.featureCollection(m)))
.map((m) => m.features)
.flat()
Insert cell
water_nest = d3
.nest()
.key(function (d) {
return d.properties.kind;
})
.entries(geom_water)
Insert cell
// geom_water = silverpeak.features
// .filter((f) => f.geometry.type != "MultiLineString")
// .filter((f) => f.geometry.type != "LineString")
// .filter((f) => f.geometry.type != "Point")
Insert cell
geom_water = mb_water
.map((m) => m.water)
.filter((m) => m != undefined)
.map((m) => m.features)
.flat()
.filter((f) => f.geometry.type != "MultiLineString")
.filter((f) => f.geometry.type != "LineString")
.filter((f) => f.geometry.type != "Point")
Insert cell
roads = mb_water
.map((m) => m.road)
.filter((m) => m != undefined)
.map((m) => m.features)
.flat()
.filter((m) => m.geometry.type != "Point")
.filter((m) => m.properties.class != "construction")
.filter((m) => m.properties.class != "service")
.filter((m) => m.properties.class != "pedestrian")
.filter((m) => m.properties.class != "street_limited")
.filter((m) => m.properties.class != "street")
Insert cell
mb_water = Promise.all(
xyz_tiles.map(async (t) => {
let data = new vt.VectorTile(
new Protobuf(
await d3.buffer(
`https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/${t.z}/${t.x}/${t.y}.mvt?access_token=pk.eyJ1Ijoid2FzaGluZ3RvbnBvc3QiLCJhIjoibWJkTGx1SSJ9.6cMdwgs-AYrRtQsEkXlHqg`
)
)
).layers;

t.data = Object.keys(data).reduce((initialData, key) => {
initialData[key] = {
type: "FeatureCollection",
features: [...Array(data[key].length).keys()].map((item, i) => {
let feature = data[key].feature(i).toGeoJSON(t.x, t.y, t.z);
return feature;
})
};

return initialData;
}, {});

return t.data;
})
)
Insert cell
hatchpattern = function (i) {
if (i % 2 == 0) {
return PI / 3
} else {
return -(PI / 3)
}
}
Insert cell
shh = zoomed_superfunds.features
.map((f) => path(f).split("Z"))
.filter((f) => f != "")
.flat()
Insert cell
classedSplitZ = diss
.map(
(f, i) =>
f.map((m) =>
path(m)
.split("Z")
.map((s) => Polygon.fromPath(s))
.map((m) => m.getHatches(hatchpattern(i), 2, 0))
)

// .flat()
// .flat()
//
//
)
.flat()
.flat()
.filter((f) => f.length > 0)
.flat()
Insert cell
tiles = Promise.all(
xyz_tiles.map(async (t) => {
let data = new vt.VectorTile(
new Protobuf(
await d3.buffer(
`https://a.tiles.mapbox.com/v4/mapbox.mapbox-terrain-v2/${t.z}/${t.x}/${t.y}.mvt?access_token=pk.eyJ1IjoibGlmZXdpbm5pbmciLCJhIjoiYWZyWnFjMCJ9.ksAPTz72HyEjF2AOMbRNvg`
)
)
).layers;

t.data = Object.keys(data).reduce((initialData, key) => {
initialData[key] = {
type: "FeatureCollection",
features: [...Array(data[key].length).keys()].map((item, i) => {
let feature = data[key].feature(i).toGeoJSON(t.x, t.y, t.z);
return feature;
})
};

return initialData;
}, {});

return t;
})
)
Insert cell
height = 800
Insert cell
hillshade = tiles
.filter((t) => Object.keys(t.data).includes("hillshade"))
.map((h) => h.data.hillshade)
.map((h) => h.features)
.flat()
Insert cell
diss.map((m) => m.map((f) => path(f)))
Insert cell
diss = poly
.map((p) => turf.dissolve(turf.featureCollection(p)))
.map((m) => m.features)
.map((m) => m.map((m) => turf.rewind(m, { reverse: true })))
//.flat()
Insert cell
poly = hs_nest
.map((e) =>
e.values.map((v) =>
v.values
.map((h) => {
if (h.geometry.type != "Polygon") {
return turf.flatten(h).features.flat();
} else {
return h;
}
})
.flat()
)
)
.flat()
// .flat()
Insert cell
hs_nest = d3
.nest()
.key(function (d) {
return d.properties.class;
})
.key(function (d) {
return d.properties.level;
})
.entries(hillshade)
Insert cell
Protobuf = require("pbf@3/dist/pbf.js")
Insert cell
d3 = require("d3-geo@1", "d3-selection@1", "d3-fetch@1", "d3-tile@0.0", "d3-scale@2.1.2", "d3-collection@latest")
Insert cell
path = d3.geoPath(projection)
Insert cell
clip = require("polygon-clipping@0.15.3")
Insert cell
turf = require("@turf/turf@latest")
Insert cell
vt = require('https://bundle.run/@mapbox/vector-tile@1.3.1')
Insert cell
import { Polygon, PI } from "@makio135/utilities"
Insert cell
xyz = require("https://bundle.run/xyz-affair@0.9.1")
Insert cell
ongoing = rwqcb.features.filter((r) => r.properties.STATUS.includes("OPEN"))
Insert cell
rwqcb = FileAttachment("rwqcb-expanded.geojson").json()
Insert cell
scc_plumes = FileAttachment("scc_plumes@1.geojson")
Insert cell
santaClara = groundwaterbasins.features
.filter((g) => g.properties.Basin_Name.includes("SANTA CLARA"))
.map((m) => turf.rewind(m, { reverse: true }))
Insert cell
groundwaterbasins = FileAttachment("GroundwaterBasins.geojson").json()
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