| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // Offline orthoimagery contact sheet with the original footprint outlines, no invented infill.
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
- import { resolve } from 'node:path'
- import { PNG } from 'pngjs'
- import jpeg from 'jpeg-js'
- const dir = process.env.GIS_DIR || 'D:/GIS/GIS'
- const data = JSON.parse(readFileSync(dir + '/planet_110.059,28.258_110.744,28.625-shp/shpOutput/buildings.json'))
- const out = resolve('.scratch/cockpit-shell-panel-layout/verify/artifacts/t35/imagery')
- mkdirSync(out, { recursive: true })
- const px = (lon, lat, z) => [
- ((lon + 180) / 360) * 2 ** z * 256,
- ((1 - Math.asinh(Math.tan((lat * Math.PI) / 180)) / Math.PI) / 2) * 2 ** z * 256,
- ]
- const sets = [
- ['south', 110.401, 28.428, 18],
- ['north', 110.395, 28.454, 18],
- ]
- for (const [name, lon, lat, z] of sets) {
- const center = px(lon, lat, z)
- const x0 = Math.floor(center[0] / 256) - 3,
- y0 = Math.floor(center[1] / 256) - 3
- const img = new PNG({ width: 1792, height: 1792 })
- img.data.fill(255)
- let tiles = 0
- for (let y = 0; y < 7; y++)
- for (let x = 0; x < 7; x++) {
- const file = dir + `/yuanlingPic3/${z}/${x0 + x}/${2 ** z - 1 - (y0 + y)}.png`
- if (!existsSync(file)) continue
- const bytes = readFileSync(file)
- const t = bytes[0] === 0xff ? jpeg.decode(bytes) : PNG.sync.read(bytes)
- PNG.bitblt(t, img, 0, 0, 256, 256, x * 256, y * 256)
- tiles++
- }
- writeFileSync(resolve(out, name + '-satellite.png'), PNG.sync.write(img))
- function line(a, b) {
- let steps = Math.ceil(Math.hypot(b[0] - a[0], b[1] - a[1]))
- for (let i = 0; i <= steps; i++) {
- let x = Math.round(a[0] + ((b[0] - a[0]) * i) / steps),
- y = Math.round(a[1] + ((b[1] - a[1]) * i) / steps)
- if (x < 0 || y < 0 || x >= img.width || y >= img.height) continue
- const k = (y * img.width + x) * 4
- img.data[k] = 255
- img.data[k + 1] = 208
- img.data[k + 2] = 0
- }
- }
- const inside = []
- for (const f of data.features) {
- let rings =
- f.geometry.type === 'Polygon' ? [f.geometry.coordinates[0]] : f.geometry.coordinates.map((p) => p[0])
- for (const r of rings) {
- let p = r.map((c) => {
- let a = px(...c, z)
- return [a[0] - x0 * 256, a[1] - y0 * 256]
- })
- if (p.every((c) => c[0] >= 0 && c[1] >= 0 && c[0] < img.width && c[1] < img.height)) {
- inside.push({ id: String(f.properties.osm_id), ring: r, px: p })
- for (let i = 1; i < p.length; i++) line(p[i - 1], p[i])
- }
- }
- }
- writeFileSync(resolve(out, name + '-footprints.png'), PNG.sync.write(img))
- writeFileSync(
- resolve(out, name + '-source.json'),
- JSON.stringify({ z, x0, y0, width: 1792, features: inside }, null, 2)
- )
- console.log({ name, tiles, footprints: inside.length, out })
- }
|