BangleApps/apps/spacew/prep/split.js

178 lines
4.4 KiB
JavaScript
Raw Normal View History

#!/usr/bin/nodejs --max-old-space-size=5500
// npm install geojson-vt
// docs: https://github.com/mapbox/geojson-vt
// output format: https://github.com/mapbox/vector-tile-spec/
const fs = require('fs');
const sphm = require('./sphericalmercator.js');
var split = require('geojson-vt')
// delme.json needs to be real file, symlink to geojson will not work
console.log("Loading json");
var gjs = require("./delme.json");
function tileToLatLon(x, y, z, x_, y_) {
var [ w, s, e, n ] = merc.bbox(x, y, z);
var lon = (e - w) * (x_ / 4096) + w;
var lat = (n - s) * (1-(y_ / 4096)) + s;
//console.log("to ", lon, lat);
return [ lon, lat ];
}
function convGeom(tile, geom) {
var g = [];
for (i = 0; i< geom.length; i++) {
var x = geom[i][0];
var y = geom[i][1];
//console.log("Geometry: ", geom, geom.length, "X,y", x, y);
var pos = tileToLatLon(tile.x, tile.y, tile.z, x, y);
g.push(pos);
}
return g;
}
function zoomPoint(tags) {
var z = 99;
if (tags.place == "city") z = 4;
if (tags.place == "town") z = 8;
if (tags.place == "village") z = 10;
return z;
}
function paintPoint(tags) {
var p = {};
if (tags.place == "village") p["marker-color"] = "#ff0000";
return p;
}
function zoomWay(tags) {
var z = 99;
if (tags.highway == "motorway") z = 7;
if (tags.highway == "primary") z = 9;
if (tags.highway == "secondary") z = 13;
if (tags.highway == "tertiary") z = 14;
if (tags.highway == "unclassified") z = 16;
if (tags.highway == "residential") z = 17;
if (tags.highway == "track") z = 17;
if (tags.highway == "path") z = 17;
if (tags.highway == "footway") z = 17;
return z;
}
function paintWay(tags) {
var p = {};
if (tags.highway == "motorway" || tags.highway == "primary") /* ok */;
if (tags.highway == "secondary" || tags.highway == "tertiary") p.stroke = "#0000ff";
if (tags.highway == "tertiary" || tags.highway == "unclassified" || tags.highway == "residential") p.stroke = "#00ff00";
if (tags.highway == "track") p.stroke = "#ff0000";
if (tags.highway == "path" || tags.highway == "footway") p.stroke = "#800000";
return p;
}
function writeFeatures(name, feat)
{
var n = {};
n.type = "FeatureCollection";
n.features = feat;
fs.writeFile(name+'.json', JSON.stringify(n), on_error);
}
function toGjson(name, d, tile) {
var cnt = 0;
var feat = [];
for (var a of d) {
var f = {};
var zoom = 99;
var p = {};
f.properties = a.tags;
f.type = "Feature";
f.geometry = {};
if (a.type == 1) {
f.geometry.type = "Point";
f.geometry.coordinates = convGeom(tile, a.geometry)[0];
zoom = zoomPoint(a.tags);
p = paintPoint(a.tags);
} else if (a.type == 2) {
f.geometry.type = "LineString";
f.geometry.coordinates = convGeom(tile, a.geometry[0]);
zoom = zoomWay(a.tags);
p = paintWay(a.tags);
} else {
//console.log("Unknown type", a.type);
}
//zoom -= 4; // Produces way nicer map, at expense of space.
if (tile.z < zoom)
continue;
f.properties = Object.assign({}, f.properties, p);
feat.push(f);
var s = JSON.stringify(feat);
if (s.length > 6000) {
console.log("tile too big, splitting", cnt);
writeFeatures(name+'-'+cnt++, feat);
feat = [];
}
}
writeFeatures(name+'-'+cnt, feat);
return n;
}
function writeTile(name, d, tile) {
toGjson(name, d, tile)
}
// By default, precomputes up to z30
var merc = new sphm({
size: 256,
antimeridian: true
});
//console.log(merc.ll([124, 123], 15));
//console.log(merc.px([17734, 11102], 15));
//console.log(merc.bbox(17734, 11102, 15));
//return;
console.log("Splitting data");
var meta = {}
meta.min_zoom = 0;
meta.max_zoom = 17; // HERE
// = 16 ... split3 takes > 30 minutes
// = 13 ... 2 minutes
var index = split(gjs, Object.assign({
maxZoom: meta.max_zoom,
indexMaxZoom: meta.max_zoom,
indexMaxPoints: 0,
tolerance: 30,
}), {});
console.log("Producing output");
var output = {};
function on_error(e) {
if (e) { console.log(e); }
}
var num = 0;
for (const id in index.tiles) {
const tile = index.tiles[id];
const z = tile.z;
console.log(num++, ":", tile.x, tile.y, z);
var d = index.getTile(z, tile.x, tile.y).features;
//console.log(d);
var n = `delme/z${z}-${tile.x}-${tile.y}` ;
//output[n] = d;
//console.log(n);
writeTile(n, d, tile)
}
fs.writeFile('delme/meta.json', JSON.stringify(meta), on_error);