Dynamically render subnets and grid lines

This commit is contained in:
LilyRose2798 2024-04-08 22:59:54 +10:00
parent 33fa08ad11
commit 5c59bf3bc8
2 changed files with 46 additions and 91 deletions

View File

@ -201,7 +201,6 @@
touchPitch: false, touchPitch: false,
style: { style: {
version: 8, version: 8,
glyphs: "assets/glyphs/{fontstack}/{range}.pbf",
sources: {}, sources: {},
layers: [] layers: []
}, },
@ -213,12 +212,48 @@
map.painter.context.extTextureFilterAnisotropic = undefined map.painter.context.extTextureFilterAnisotropic = undefined
map.touchZoomRotate.disableRotation() map.touchZoomRotate.disableRotation()
const tileSize = 256
const tilesDir = "assets/tiles" const tilesDir = "assets/tiles"
const tilesId = "ipmap-tiles" const tilesId = "ipmap-tiles"
const privateRangesId = "private-ranges" const privateRangesId = "private-ranges"
const subnetsId = "subnets"
const dataP = fetch(`${tilesDir}/tiles.json`, { cache: "no-store" }).then(res => res.json()) const dataP = fetch(`${tilesDir}/tiles.json`, { cache: "no-store" }).then(res => res.json())
const privateRangePatternP = map.loadImage("assets/private-range-pattern.png") const privateRangePatternP = map.loadImage("assets/private-range-pattern.png")
const canvas = document.createElement("canvas")
const canvasScale = window.devicePixelRatio
canvas.width = tileSize * canvasScale
canvas.height = tileSize * canvasScale
const ctx = canvas.getContext("2d")
ctx.scale(canvasScale, canvasScale)
ctx.fillStyle = "white"
ctx.lineWidth = 3
ctx.font = "bold 20px sans-serif"
maplibregl.addProtocol(subnetsId, async (params, abortController) => {
console.log(params.url)
const [z, y, x] = params.url.split("://")[1].split("/")
const width = 2 ** z
const subnet = 2 * z
const hy = Math.floor(0x10000 * (y / width))
const hx = Math.floor(0x10000 * (x / width))
const text = ipToRange(coordsToHilbert({ x: hx, y: hy }), subnet)
const metrics = ctx.measureText(text)
const cy = tileSize / 2 + metrics.actualBoundingBoxAscent / 2
const cx = tileSize / 2 - metrics.actualBoundingBoxRight / 2
ctx.clearRect(0, 0, tileSize, tileSize)
ctx.moveTo(0, 0)
ctx.lineTo(tileSize, 0)
ctx.lineTo(tileSize, tileSize)
ctx.lineTo(0, tileSize)
ctx.lineTo(0, 0)
ctx.strokeStyle = "white"
ctx.stroke()
ctx.strokeStyle = "black"
ctx.strokeText(text, cx, cy)
ctx.fillText(text, cx, cy)
return { data: await new Promise((res, rej) => canvas.toBlob(b => b.arrayBuffer().then(res))) }
})
map.once("style.load", async () => { map.once("style.load", async () => {
const data = await dataP const data = await dataP
const flatData = Object.entries(data) const flatData = Object.entries(data)
@ -239,7 +274,7 @@
map.addSource(tilesId, { map.addSource(tilesId, {
type: "raster", type: "raster",
tiles: [`${tilesDir}/${curDate}/${curVariant}/${curColormap}/{z}/{y}/{x}.png`], tiles: [`${tilesDir}/${curDate}/${curVariant}/${curColormap}/{z}/{y}/{x}.png`],
tileSize: 256, tileSize,
minzoom: 0, minzoom: 0,
maxzoom: 8, maxzoom: 8,
}) })
@ -295,99 +330,19 @@
type: "fill", type: "fill",
source: privateRangesId, source: privateRangesId,
paint: { paint: {
"fill-color": "#0000FF",
"fill-pattern": privateRangePatternId "fill-pattern": privateRangePatternId
} }
}) })
const zoomLevels = 8 map.addSource(subnetsId, {
;[...Array(zoomLevels)].map((_, i) => i + 1).forEach(z => { type: "raster",
const labelsId = `subnet-labels-${z}` tiles: [`${subnetsId}://{z}/{y}/{x}`],
const width = 2 ** z tileSize,
const subnet = 2 * z })
const moff = 0.5 / width map.addLayer({
const hoff = Math.floor(0x10000 * moff) id: subnetsId,
map.addSource(labelsId, { type: "raster",
type: "geojson", source: subnetsId,
data: {
type: "FeatureCollection",
features: [...Array(width)].flatMap((_, y) => {
const ny = y / width
const my = ny + moff
const hy = Math.floor(0x10000 * ny)
return [...Array(width)].map((_, x) => {
const nx = x / width
const mx = nx + moff
const hx = Math.floor(0x10000 * nx)
return {
type: "Feature",
geometry: {
type: "Point",
coordinates: new maplibregl.MercatorCoordinate(mx, my, 0).toLngLat().toArray()
},
properties: {
name: ipToRange(coordsToHilbert({ x: hx, y: hy }), subnet)
}
}
})
})
}
})
map.addLayer({
id: labelsId,
type: "symbol",
source: labelsId,
minzoom: Math.max(z - 1.5, 0),
...(z < zoomLevels ? { maxzoom: z - 0.5 } : {}),
layout: {
"text-field": "{name}",
"text-font": ["Open Sans Bold"],
"text-size": 22
},
paint: {
"text-color": "#FFFFFF"
}
})
const gridId = `grid-lines-${z}`
map.addSource(gridId, {
type: "geojson",
data: {
type: "FeatureCollection",
features: [...Array(width + 1)].map((_, i) => i / width).flatMap(i => [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
new maplibregl.MercatorCoordinate(i, 0, 0).toLngLat().toArray(),
new maplibregl.MercatorCoordinate(i, 1, 0).toLngLat().toArray(),
]
}
}, {
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
new maplibregl.MercatorCoordinate(0, i, 0).toLngLat().toArray(),
new maplibregl.MercatorCoordinate(1, i, 0).toLngLat().toArray(),
]
}
}
])
}
})
map.addLayer({
id: gridId,
type: "line",
source: gridId,
minzoom: Math.max(z - 1.5, 0),
...(z < zoomLevels ? { maxzoom: z - 0.5 } : {}),
paint: {
"line-color": "#FFFFFF",
"line-width": 3
}
})
}) })
const setStyle = (date, variant, colormap) => { const setStyle = (date, variant, colormap) => {