Dynamically render subnets and grid lines
This commit is contained in:
parent
33fa08ad11
commit
5c59bf3bc8
Binary file not shown.
|
@ -201,7 +201,6 @@
|
|||
touchPitch: false,
|
||||
style: {
|
||||
version: 8,
|
||||
glyphs: "assets/glyphs/{fontstack}/{range}.pbf",
|
||||
sources: {},
|
||||
layers: []
|
||||
},
|
||||
|
@ -213,12 +212,48 @@
|
|||
map.painter.context.extTextureFilterAnisotropic = undefined
|
||||
map.touchZoomRotate.disableRotation()
|
||||
|
||||
const tileSize = 256
|
||||
const tilesDir = "assets/tiles"
|
||||
const tilesId = "ipmap-tiles"
|
||||
const privateRangesId = "private-ranges"
|
||||
const subnetsId = "subnets"
|
||||
const dataP = fetch(`${tilesDir}/tiles.json`, { cache: "no-store" }).then(res => res.json())
|
||||
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 () => {
|
||||
const data = await dataP
|
||||
const flatData = Object.entries(data)
|
||||
|
@ -239,7 +274,7 @@
|
|||
map.addSource(tilesId, {
|
||||
type: "raster",
|
||||
tiles: [`${tilesDir}/${curDate}/${curVariant}/${curColormap}/{z}/{y}/{x}.png`],
|
||||
tileSize: 256,
|
||||
tileSize,
|
||||
minzoom: 0,
|
||||
maxzoom: 8,
|
||||
})
|
||||
|
@ -295,99 +330,19 @@
|
|||
type: "fill",
|
||||
source: privateRangesId,
|
||||
paint: {
|
||||
"fill-color": "#0000FF",
|
||||
"fill-pattern": privateRangePatternId
|
||||
}
|
||||
})
|
||||
|
||||
const zoomLevels = 8
|
||||
;[...Array(zoomLevels)].map((_, i) => i + 1).forEach(z => {
|
||||
const labelsId = `subnet-labels-${z}`
|
||||
const width = 2 ** z
|
||||
const subnet = 2 * z
|
||||
const moff = 0.5 / width
|
||||
const hoff = Math.floor(0x10000 * moff)
|
||||
map.addSource(labelsId, {
|
||||
type: "geojson",
|
||||
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
|
||||
}
|
||||
})
|
||||
map.addSource(subnetsId, {
|
||||
type: "raster",
|
||||
tiles: [`${subnetsId}://{z}/{y}/{x}`],
|
||||
tileSize,
|
||||
})
|
||||
map.addLayer({
|
||||
id: subnetsId,
|
||||
type: "raster",
|
||||
source: subnetsId,
|
||||
})
|
||||
|
||||
const setStyle = (date, variant, colormap) => {
|
||||
|
|
Loading…
Reference in New Issue