Public
Edited
Jan 2, 2024
Insert cell
Insert cell
map = svg`<svg viewBox="0 0 ${width} ${height}">

<g id = "hillshade">
${circleHatch.map(
(h, i) =>
`<path d ='M${[h.a.x, h.a.y]}L${[
h.b.x,
h.b.y
]}' stroke="goldenrod" opacity="0.5"/>`
)}
</g>

</svg>`
Insert cell
Insert cell
Insert cell
height = 600
Insert cell
Insert cell
viewof file = Inputs.file({ label: "Upload geoJSON" })
Insert cell
map24 = FileAttachment("map (24).geojson").json()
Insert cell
map23 = FileAttachment("map (23).geojson").json()
Insert cell
//if you want to use a different file change this to file.json()
boundsfile = map1
Insert cell
Insert cell
xyz_tiles = xyz(bounds, 12)
Insert cell
bldgs = FileAttachment("shinetsuWA-bldgs.geojson").json()
Insert cell
Insert cell
zoomed_bbox = turf.bboxPolygon(
turf.bbox(
turf.buffer(turf.bboxPolygon(turf.bbox(boundsfile)), 1, {
unit: "miles"
})
)
)
Insert cell
site = zoomed_bbox
Insert cell
bounds = [
site.geometry.coordinates[0][0],
site.geometry.coordinates[0][2]
]
Insert cell
rewind = turf.rewind(site, { reverse: true })
Insert cell
ctr = turf.center(site)
Insert cell
projection = d3
.geoMercator()
.center(ctr.geometry.coordinates)
.translate([0, 0])
.fitSize([width, height], rewind)
Insert cell
Insert cell
Insert cell
tile_bldgs = mb_water
.map((m) => m.building)
.filter((f) => f != undefined)
.map((m) => m.features)
.flat()
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=${mapbox}`
)
)
).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
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")
.flat()
Insert cell
poly_water = geom_water
.map((v) => {
if (v.geometry.type != "Polygon") {
return turf.flatten(v).features.flat();
} else {
return v;
}
})
.flat()
Insert cell
multipolygon = turf.rewind(
poly_water.reduce((p, m) => turf.union(p, m)),
{ reverse: true }
)
Insert cell
tessel = turf
.flatten(multipolygon)
.features.map((m) => turf.tesselate(m))
.map((m) => m.features)
.flat()
Insert cell
waterHatch = tessel
.map(
(m, i) =>
path(m)
.split("M")
.filter((f) => f != "")
.map((m) => "M" + m)
//.map((m) => m.split("Z"))
)
.map((s) => Polygon.fromPath(s))
.map((m) => m.getHatches(PI / 3, 1.5, 0))
.filter((f) => f.length > 0)
Insert cell
Insert cell
mapbox = "pk.eyJ1IjoibW91cm5lciIsImEiOiJjbG1rYjV0bDAwMHh3MnFxZ3Vya2JwaW90In0.t0eyyT3HaM4vnj_3IXFkBQ"
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=${mapbox}`
)
)
).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
Insert cell
hillshade = tiles
.filter((t) => Object.keys(t.data).includes("hillshade"))
.map((h) => h.data.hillshade)
.map((h) => h.features)
.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
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
clipFlat = poly
.map((c) =>
c
.map((m) => turf.flatten(m))
.map((l) => l.features)
.flat()
.map((m) => turf.rewind(m))
)
.map((c) =>
turf
.dissolve(turf.featureCollection(c))
.features.map((m) => turf.rewind(m, { reverse: true }))
)
Insert cell
circle_clip = clipFlat
.flat()
.map((m) => {
let int = turf.intersect(m, map1.features[0]);
return int;
})
.filter((f) => f != null)
Insert cell
Insert cell
hatchpattern = function (i) {
if (i % 2 == 0) {
return PI / 3
} else {
return -(PI / 3)
}
}
Insert cell
Insert cell
circleHatch = circle_clip
.map((m, i) =>
path(m)
.split("Z")
.map((s) => Polygon.fromPath(s))
.map((m) => m.getHatches(hatchpattern(i), 3, 0))
)

.flat()
.filter((f) => f.length > 0)
.flat()
Insert cell
Insert cell
clip = require("polygon-clipping@0.15.3")
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
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
map7 = FileAttachment("map(7).geojson").json()
Insert cell
map1 = FileAttachment("map (1).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