Public
Edited
Oct 5, 2024
Insert cell
Insert cell
//if you want to use a different file use the file upload thing and change this to file.json()
boundsfile = lebanon
Insert cell
viewof file = Inputs.file({ label: "Upload geoJSON" })
Insert cell
//get tiles needed at specific zoom (this kind of affects detail of your resulting image? but mostly it affects how slowly it loads lol)
xyz_tiles = xyz(bounds, 9)
Insert cell
california = FileAttachment("california.geojson").json()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
levels = 18
Insert cell
canvasMap = {
// generic water color: "rgb(1, 134,160)"
let ctx = DOM.context2d(width, height);
// const path = d3.geoPath(projection, ctx);
// ctx.fillStyle = "rgb(1, 134,160)";
// ctx.fillRect(0, 0, width, height);
// ctx.save();
// ctx.beginPath(), path(boundsfile), ctx.clip();

xyz_tiles.map((t, i) => {
let tile = new Image();
tile.src = base64[i];
ctx.drawImage(
tile,
projection(tile_bbox[i].coordinates[0][0])[0],
projection(tile_bbox[i].coordinates[0][0])[1],
tileScale,
tileScale
);
});
ctx.save();
ctx.strokeStyle = "rgb(0,0,0)";
ctx.beginPath(),
path(turf.rewind(langata_cemetery_outline, { reverse: true })),
ctx.stroke();

return ctx.canvas;
}
Insert cell
langata01 = FileAttachment("langata01.geojson").json()
Insert cell
diamantina = FileAttachment("diamantina.geojson").json()
Insert cell
langata_cemetery_outline = FileAttachment("langata_cemetery_outline.geojson").json()
Insert cell
tileScale = projected[3][0] - projected[0][0] + 1
Insert cell
width = 600
Insert cell
selected = canvasMap
Insert cell
tileSize = selected.width
Insert cell
gridSize = tileSize
Insert cell
Insert cell
Insert cell
size = Math.sqrt(terrain.length)
Insert cell
heightExtent = d3.extent(terrain)
Insert cell
Insert cell
Insert cell
Insert cell
xScale = d3.scaleLinear().domain([0, size]).range([-10, 10])
Insert cell
yScale = d3.scaleLinear().domain([0, size]).range([-10, 10])
Insert cell
zScale = d3.scaleLinear().domain(heightExtent).range([0, terrainExaggeration])
Insert cell
edges = Object.assign({
top: terrainMatrix[0],
bottom: terrainMatrix[terrainMatrix.length - 1],
left: terrainMatrix.map((r) => r[0]),
right: terrainMatrix.map((r) => r[terrainMatrix.length - 1])
})
Insert cell
parameters = Object.assign({ ...worldParameters, ...perspectiveParameters })
Insert cell
projectedIsobands = {
const shapes = [];

isolines.forEach((lvl, i) => {
//lvl.lines.forEach((isoline) => {
//const lvl = isolines[levelIndex]
lvl.lines.forEach((isoline) => {
let entity = simplify(
isoline.map((d) => {
return { x: d[0], y: d[1] };
}),
lineSimplification
).map((c) => {
let copy = [xScale(c.x), yScale(c.y), zScale(lvl.threshold), 1];

return copy;
});

entity.closed = true;
entity.fillColor = "none";
entity.strokeWidth = 0.5;
entity.level = i;
entity.elevation = lvl.threshold;

shapes.push(entity);
});
});

return processScene(shapes, parameters);
}
Insert cell
scene = {
let scene = [];
let scale = 0.075;

//const allRings = []
isolines.forEach((lvl, i) => {
//lvl.lines.forEach((isoline) => {
//const lvl = isolines[levelIndex]
lvl.lines.forEach((isoline) => {
let entity = simplify(
isoline.map((d) => {
return { x: d[0], y: d[1] };
}),
lineSimplification
).map((c) => {
let copy = [xScale(c.x), yScale(c.y), zScale(lvl.threshold), 1];

return copy;
});

entity.closed = true;
entity.fillColor = "#fff";
entity.strokeWidth = 0.5;
entity.groupname = `group${lvl.threshold}`;

scene.push(entity);
});
});

// scene.push(label);

// const east = [[14, 0, terrainExaggeration / 2, 1]];
// east.text = "E";
// east.textAnchor = "middle";

// const west = [[-14, 0, terrainExaggeration / 2, 1]];
// west.text = "W";
// west.textAnchor = "middle";

// const south = [[0, 14, terrainExaggeration / 2, 1]];
// south.text = "S";
// south.textAnchor = "middle";

// const north = [[0, -14, terrainExaggeration / 2, 1]];
// north.text = "N";
// north.textAnchor = "middle";

// scene.push(north);
// scene.push(south);
// scene.push(east);
// scene.push(west);

return scene;
}
Insert cell
processedScene = {
var t0 = performance.now();
const result = processScene(scene, parameters);
var t1 = performance.now();

console.log(`processor: ${t1 - t0}`);

return result;
}
Insert cell
processedscene_layer = d3
.nest()
.key((d) => d.groupname)
.entries(processedScene)
.map((m) => {
m.values.flat();
return m;
})
Insert cell
anaglyphRenderer = (processedScene) => {
var t0 = performance.now();

const leftLayer = [];
const rightLayer = [];

const behindProjectionPlane = (item) => {
return item.map((points) => {
points.map((d) => d[0][2]).find((d) => d <= 0) === undefined &&
points.map((d) => d[1][2]).find((d) => d <= 0) === undefined;
});

return true;
};

let allLeftPath = "";
let allRightPath = "";

const svgStuff = processedscene_layer.map((m) => {
leftLayer.push(
svg`<g id=${m.key}>${m.values
.filter(behindProjectionPlane)
.map((item) => {
const leftPath =
"M " +
item.map((p) => `${p[0][0]} ${p[0][1]}`).join(" L ") +
(item.closed ? " Z" : "");
const rightPath =
"M " +
item.map((p) => `${p[1][0]} ${p[1][1]}`).join(" L ") +
(item.closed ? " Z" : "");

// allLeftPath += ' ' + leftPath
// allRightPath += ' ' + rightPath

return svg`<path d="${leftPath}" fill="${
item.fillColor ? item.fillColor : "none"
}" stroke="black" stroke-width="${
item.strokeWidth ? item.strokeWidth : 1
}"/>`;
})}</g>`
);
});

// if (allLeftPath !== '') {
// leftLayer.push(svg`<path d="${allLeftPath}" fill="white" stroke="${colors.left}" stroke-width="1" style="mix-blend-mode: multiply;" />`)
// }

// if (allRightPath !== '') {
// rightLayer.push(svg`<path d="${allRightPath}" fill="white" stroke="${colors.right}" stroke-width="1" style="mix-blend-mode: multiply;" />`)
// }

var t1 = performance.now();

console.log(`renderer: ${t1 - t0}`);

return svg`<g>
<g transform="translate(${tileSize / 2},${
tileSize / 2
})" style="mix-blend-mode: multiply;">
${rightLayer}
</g>
<g transform="translate(${tileSize / 2},${
tileSize / 2
})" style="mix-blend-mode: multiply;">
${leftLayer}
</g>
</g>`;
}
Insert cell
import {
renderer,
processScene
} with { height } from "@tonyhschu/anaglyph-pipeline-in-gpujs"
Insert cell
import { rasterize } from "@mbostock/saving-svg"
Insert cell
Insert cell
Insert cell
height = 600
Insert cell
Insert cell
Insert cell
Insert cell
zoomed_bbox = turf.bboxPolygon(
turf.bbox(
turf.buffer(turf.bboxPolygon(turf.bbox(boundsfile)), 0, {
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])
//.scale(Math.pow(2, 21) / (2 * Math.PI))
.fitSize([width, height], rewind)
Insert cell
Insert cell
projected = tile_bbox[0].coordinates[0].map((t) => projection(t))
Insert cell
xyz_tiles
Insert cell
tile_bbox = xyz_tiles.map((t) => tilebelt.tileToGeoJSON([t.x, t.y, t.z]))
Insert cell
base64 = Promise.all(
xyz_tiles.map(async (t) => {
let image = await canvas(t);
return await image.toDataURL();
})
)
Insert cell
canvas = async (t) => {
let img = new Image();
img.crossOrigin = "anonymous";
img.src = url(t);
await new Promise((resolve) => img.addEventListener("load", resolve));
let ctx = DOM.canvas(img.width, img.height).getContext("2d");
ctx.drawImage(img, 0, 0);
return ctx.canvas;
}
Insert cell
canvas(xyz_tiles[0])
Insert cell
url = (t) =>
`https://api.mapbox.com/v4/mapbox.terrain-rgb/${t.z}/${t.x}/${t.y}.png?access_token=${mapbox}`
Insert cell
sfbay = FileAttachment("sfbay.geojson").json()
Insert cell
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", "d3-array@3", "d3")
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
tilebelt = import("https://cdn.skypack.dev/@mapbox/tilebelt@1.0.2?min")
Insert cell
mapbox = "pk.eyJ1IjoibGlmZXdpbm5pbmciLCJhIjoiY2t6bXA2dWZlMmtzbTJ2bjJ0ZTdwYnoyNyJ9.cF_Xt3B9htHIUD0lAKXaRg"
Insert cell
MarchingSquares = import(
"https://unpkg.com/marchingsquares@1.3.3/dist/marchingsquares-esm.js?module"
)
Insert cell
simplify = require("simplify-js")
Insert cell
import { view } from "@tomlarkworthy/view"
Insert cell
bingham = FileAttachment("bingham.geojson").json()
Insert cell
af = FileAttachment("af.geojson").json()
Insert cell
langata02 = FileAttachment("langata02.geojson").json()
Insert cell
lebanon = FileAttachment("lebanon.json").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