Published
Edited
Dec 22, 2021
1 fork
3 stars
Insert cell
Insert cell
Insert cell
justlines = svg`<svg viewBox="0 0 ${width} ${height}" clip-path="url(#myClip)">
<defs>
<clipPath id="myClip">
<circle cx="${width / 2}" cy="${height / 2}" r="${width / 4}" fill="pink" />
</clipPath>
</defs>
<g id = "lines">
${hs_nest.map(
(n) =>
`<g id = '${n.key}'>
${n.values.map(
(v) =>
`<g id = 'level${v.key}'>
${v.values.map(
(m) =>
`${renderHatches(
m,
1,
color[set.indexOf(m.properties.level)]
)}
</g>`
)}
</g>`
)}
</g>`
)}
</g>
</g>
</svg>`
Insert cell
opacitycheck = svg`<svg viewBox="0 0 ${width} ${height}" clip-path="url(#myClip)">
<defs>
<clipPath id="myClip">
<circle cx="${width / 2}" cy="${height / 2}" r="${width / 4}" fill="pink" />
</clipPath>
</defs>
<g id = "lines">
${hs_nest.map(
(n) =>
`<g id = '${n.key}'>
${n.values.map(
(v) =>
`<g id = 'level${v.key}'>
${v.values.map(
(m) =>
`${renderHatches(m, 1, "mediumpurple")}
</g>`
)}
</g>`
)}
</g>`
)}
</g>
</g>
</svg>`
Insert cell
byclassmap = svg`<svg viewBox="0 0 ${width} ${height}" clip-path='url(#myClip)'>
<defs>
<clipPath id="myClip">
<circle cx="${width / 2}" cy="${height / 2}" r="${width / 4}" fill="pink" />
</clipPath>
</defs>
<g clip-path = 'url(#myClip)'>
${test02.features.map(
(n) =>
`<g id = ${n.properties.class}>
${renderHatches(n, 2, color[set.indexOf(n.properties.level)])}
`
)}
</g>
</svg>`
Insert cell
set = Array.from(new Set(hillshade.map((e) => e.properties.level).sort()))
Insert cell
Insert cell
hillshade = tiles
.map((t) => t.data.hillshade)
.map((h) => h.features)
.flat()
Insert cell
Insert cell
test02 = turf.featureCollection(
polygons_class.map((p) =>
turf.multiPolygon(clip.union(p.map((l) => l.geometry.coordinates)), {
level: p[0].properties.level
})
)
)
// turf.multiPolygon(
// clip.union(polygons[0][1].map((p) => p.geometry.coordinates))
// )
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()
Insert cell
polygons_class = hs_nest_class.map((e) =>
e.values
.map((h) => {
if (h.geometry.type != "Polygon") {
return turf.flatten(h).features.flat();
} else {
return h;
}
})
.flat()
)
Insert cell
hs_nest_class = d3
.nest()
.key(function (d) {
return d.properties.class;
})
.entries(hillshade)
Insert cell
hs_nest = d3
.nest()
.key(function (d) {
return d.properties.class;
})
.key(function (d) {
return d.properties.level;
})
.entries(hillshade)
Insert cell
tiles = Promise.all(tile().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.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;
}))
Insert cell
projection.preclip(clipPolygon)
Insert cell
Protobuf = require('pbf')
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", "d3-geo-polygon@latest")
Insert cell
projection = d3
.geoMercator()
.center([-65.995, -18.927])
.scale(1000000 / (2 * Math.PI))
.translate([width / 2, height / 2])
Insert cell
tile = d3.tile()
.size([width, height])
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0,0]))
Insert cell
height = 800
Insert cell
path = d3.geoPath(projection)
Insert cell
clip = require("polygon-clipping@0.15.3")
Insert cell
turf = require("@turf/turf@5")
Insert cell
vt = require('https://bundle.run/@mapbox/vector-tile@1.3.1')
Insert cell
merge = require("https://bundle.run/@mapbox/geojson-merge@1.1.1")
Insert cell
lint = require("https://bundle.run/@mapbox/geojsonhint@3.0.1")
Insert cell
import { intersections } from "@fil/fill-with-stroke"
Insert cell
//generalizing from @fil's version

function renderHatches(data, step, color) {
//d3.select(m).select("path.lines").remove();

const poly = polygons(projection, data);

const lines = [];

for (let y = 0; y < width; y += step) {
let A = intersections(poly, y);
for (let i = 0; i < A.length - 1; i += 2) {
if (A[i + 1] - A[i] > 1 * step)
lines.push({
x1: A[i] + step * 0.5,
x2: A[i + 1] - step * 0.5,
y1: y,
y2: y
});
}
}
return `<path d=${lines
.map((d) => `M${[d.x1, d.y1]}L${[d.x2, d.y2]}`)
.join("")} stroke=${color} stroke-opacity=0.5 ></path>`;
// d3.select(m)
// .append("path")
// .attr("d", lines.map((d) => `M${[d.x1, d.y1]}L${[d.x2, d.y2]}`).join(""))
// .classed("lines", true)
// .attr("stroke", "brown");
}
Insert cell
polygons = function (projection, data) {
const path = d3.geoPath(projection);

return path(data)
.split(/M/)
.filter((d) => d)
.map((d) =>
d.split(/L/).map((d) => d.split(/,/).map((d) => parseFloat(d)))
);
}
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