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,
|
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
|
|
||||||
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({
|
map.addLayer({
|
||||||
id: labelsId,
|
id: subnetsId,
|
||||||
type: "symbol",
|
type: "raster",
|
||||||
source: labelsId,
|
source: subnetsId,
|
||||||
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) => {
|
||||||
|
|
Loading…
Reference in New Issue