ipmap/index.html

150 lines
4.2 KiB
HTML
Raw Normal View History

2024-03-31 20:21:11 -04:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="dark light">
<title>IP Map</title>
<script src="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.js"></script>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.css" />
<style>
body {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#map {
width: 100vh;
height: 100%;
margin: 0 auto;
}
.maplibregl-canvas {
cursor: pointer;
}
.maplibregl-popup-content {
background-color: #222;
font-size: 1rem;
padding: 0.8rem 1.2rem;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
function hilbert_c2i({ x, y }) {
var b, d;
var rotation = 0;
let reflection = 0;
let index = 0;
for (b = 16; b--;) {
let bits = reflection;
reflection = (y >>> b) & 1;
reflection |= ((x >>> b) & 1) << 1;
bits = bits ^ reflection;
bits = ((bits >>> rotation) | (bits << (2 - rotation))) & 3;
index |= bits << (b << 1);
reflection ^= (1 << rotation);
bits = bits & (-bits) & 1;
while (bits) { ++rotation; bits >>>= 1; }
if (++rotation >= 2) rotation -= 2;
}
index ^= 0x2aaaaaaa;
for (d = 1; d < 32; d *= 2) {
let t = index >>> d;
if (!t) break;
index ^= t;
}
return index;
}
function hilbert_i2c(index) {
var b, d, t;
var rotation = 0;
let reflection = 0;
let coord = { x: 0, y: 0 };
index ^= (index >>> 1) ^ 0x2aaaaaaa;
for (b = 16; b--; ) {
var bits = index >>> (2 * b) & 3;
reflection ^= ((bits >>> (2 - rotation)) | (bits << rotation)) & 3;
coord.x |= (reflection & 1) << b;
coord.y |= ((reflection >>> 1) & 1) << b;
reflection ^= (1 << rotation);
bits &= (-bits) & 1;
while (bits) {
bits >>>= 1;
++rotation;
}
if (++rotation >= 2)
rotation -= 2;
}
return coord;
}
const map = new maplibregl.Map({
container: "map",
attributionControl: false,
renderWorldCopies: false,
doubleClickZoom: false,
dragRotate: false,
style: {
"version": 8,
"sources": {
"raster-tiles": {
"type": "raster",
"tiles": [
"tiles/{z}/{y}/{x}.png"
],
"minzoom": 0,
"maxzoom": 8,
"tileSize": 256
}
},
"layers": [
{
"id": "simple-tiles",
"type": "raster",
"source": "raster-tiles",
"paint": {
"raster-resampling": "nearest"
}
}
]
},
center: [0, 0],
minZoom: -1,
maxZoom: 12,
zoom: 0
})
map.painter.context.extTextureFilterAnisotropic = undefined
map.addControl(new maplibregl.NavigationControl({ showCompass: false }), "top-left")
const toIp = v => `${v >> 24 & 0xFF}.${v >> 16 & 0xFF}.${v >> 8 & 0xFF}.${v >> 0 & 0xFF}`
map.on("click", (e) => {
const { x, y } = maplibregl.MercatorCoordinate.fromLngLat(e.lngLat, 0)
const rawIp = hilbert_c2i({ x: Math.floor(0x10000 * x), y: Math.floor(0x10000 * y) })
const subnet = Math.min(32, Math.round(map.getZoom()) * 2 + 18)
const text = subnet < 32 ?
`Range: ${toIp((rawIp >> (32 - subnet)) << (32 - subnet))}/${subnet}` :
`IP: ${toIp(rawIp)}`
new maplibregl.Popup()
.setHTML(text)
.setLngLat(e.lngLat)
.addTo(map)
})
</script>
</body>
</html>