diff options
Diffstat (limited to 'tools/parse-layout.js')
-rw-r--r-- | tools/parse-layout.js | 325 |
1 files changed, 37 insertions, 288 deletions
diff --git a/tools/parse-layout.js b/tools/parse-layout.js index b382849..6f77adf 100644 --- a/tools/parse-layout.js +++ b/tools/parse-layout.js @@ -1,61 +1,30 @@ "use strict" -/* COMMON PARSING */ - const fs = require("fs") let points = {} -let circles = {} -let rects = {} +let boxes = {} let edges = {} +let mode, group, name, x, y, w, h, cx, cy, rx, ry, x2, y2 let labels = [] - -let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2 - -function array_insert(array, index, item) { - for (let i = array.length; i > index; --i) - array[i] = array[i - 1] - array[index] = item -} - -function set_add(set, item) { - let a = 0 - let b = set.length - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = set[m] - if (item < x) - b = m - 1 - else if (item > x) - a = m + 1 - else - return - } - array_insert(set, a, item) -} +let labels_uniq = {} function add_point(x, y) { - if (!(name in points)) - points[name] = [] - points[name].push({x,y}) -} - -function add_circle(cx, cy, rx, ry) { - if (!(name in circles)) - circles[name] = [] - circles[name].push({x:cx-rx,y:cy-ry,w:rx*2,h:ry*2}) + if (!(group in points)) + points[group] = [] + points[group].push({x,y,name}) } function add_rect(x, y, w, h) { - if (!(name in rects)) - rects[name] = [] - rects[name].push({x,y,w,h}) + if (!(group in boxes)) + boxes[group] = [] + boxes[group].push({x,y,w,h,name}) } function add_edge(x1, y1, x2, y2) { - if (!(name in edges)) - edges[name] = [] - edges[name].push({x1,y1,x2,y2}) + if (!(group in edges)) + edges[group] = [] + edges[group].push({x1,y1,x2,y2,name}) } function flush() { @@ -64,13 +33,14 @@ function flush() { } if (mode === 'rect') { add_rect(x, y, w, h) - add_point(x + w/2, y + h/2) + add_point( x + w/2, y + h/2 ) } if (mode === 'circle') { - add_circle(cx, cy, rx, ry) - add_point(cx, cy) + add_rect(cx - rx, cy - ry, rx * 2, ry * 2) + add_point( cx, cy ) } x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 + name = null } function parse_path_data(path) { @@ -184,18 +154,23 @@ for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { else if (line.startsWith('ry="')) ry = (Number(line.split('"')[1])) else if (line.startsWith('inkscape:label="') && mode === "g") + group = line.split('"')[1] + else if (line.startsWith('inkscape:label="') && mode !== "g") name = line.split('"')[1] else if (line.startsWith('d="')) parse_path_data(line.split('"')[1].split(/[ ,]/)) if (line.includes("</tspan>")) { let name = line.replace(/^[^>]*>/, "").replace(/<\/tspan.*/, "") + if (name in labels_uniq) + console.log("DUPLICATE LABEL", name) labels.push({x, y, name}) + labels_uniq[name] = 1 } } flush() -function find_closest_label(x, y) { +function find_label(x, y, limit) { let nd = Infinity, nn = null for (let n of labels) { @@ -206,261 +181,35 @@ function find_closest_label(x, y) { } } - if (!nn) { - console.log("NOT FOUND", x, y) - return null - } - - if (nd > 50) { - console.log("NO LABEL", x, y, nd) + if (!nn || nd > limit) { + console.log("LABEL NOT FOUND", x, y) return null } return nn.name } -function find_closest_node(nodes, x, y) { - let nd = Infinity, nn = -1 - - for (let i = 0; i < nodes.length; ++i) { - let n = nodes[i] - let d = Math.hypot(n.x - x, n.y - y) - if (d < nd) { - nd = d - nn = i +for (let group in points) { + for (let item of points[group]) { + if (item.name === null) { + item.name = find_label(item.x, item.y, 72) } } - - if (nd > 100) - return -1 - - return nn } -function label_boxes(top) { - for (let key in top) { - console.log("BOX", key) - for (let item of top[key]) - item.name = find_closest_label(item.x + item.w/2, item.y + item.h/2) - } -} - -function label_points(top) { - for (let key in top) { - console.log("POINT", key) - for (let item of top[key]) - item.name = find_closest_label(item.x, item.y) - } -} - -label_boxes(rects) -label_boxes(circles) -label_points(points) - -function connect_edge_2way(node_list, edge_name) { - console.log("EDGE", edge_name) - for (let e of edges[edge_name]) { - let a = find_closest_node(node_list, e.x1, e.y1) - let b = find_closest_node(node_list, e.x2, e.y2) - if (a < 0 || b < 0) - console.log("CANNOT FIND EDGE", e, node_list[a], node_list[b]) - if (!node_list[a][edge_name]) - node_list[a][edge_name] = [] - if (!node_list[b][edge_name]) - node_list[b][edge_name] = [] - set_add(node_list[a][edge_name], b) - set_add(node_list[b][edge_name], a) - } -} - -function connect_edge_1way(a_list, b_list, edge_name, prop_name) { - console.log("EDGE", edge_name) - for (let e of edges[edge_name]) { - let a1 = find_closest_node(a_list, e.x1, e.y1) - let a2 = find_closest_node(a_list, e.x2, e.y2) - let b1 = find_closest_node(b_list, e.x1, e.y1) - let b2 = find_closest_node(b_list, e.x2, e.y2) - let a = a1 >= 0 ? a1 : a2 - let b = b1 >= 0 ? b1 : b2 - if (a < 0 || b < 0) - console.log("CANNOT FIND EDGE", e, a_list[a], b_list[b]) - if (!a_list[a][prop_name]) - a_list[a][prop_name] = [] - set_add(a_list[a][prop_name], b) - } -} - -/* WASHINGTON'S WAR */ - -function sort_alpha(list) { - list.sort((a,b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0) -} - -sort_alpha(points.fortress) -sort_alpha(points.winter_quarters) -sort_alpha(points.space) -points.colony.reverse() - -const data = {} - -data.spaces = [ ...points.fortress, ...points.winter_quarters, ...points.space ] -data.colonies = [ ...points.colony ] -data.seas = [ ...points.sea ] - -connect_edge_2way(data.spaces, "path") -connect_edge_2way(data.spaces, "wilderness") -connect_edge_1way(data.colonies, data.spaces, "colony", "spaces") -connect_edge_1way(data.seas, data.spaces, "sea", "spaces") - -console.log(JSON.stringify(data,0,4)) - -/* -function find_closest_node(list, x, y) { - let nd = Infinity, nn = null - - for (let n of list) { - let d = Math.hypot(n.x - x, n.y - y) - if (d < nd) { - nd = d - nn = n - } - } - - if (!nn) { - console.log("NOT FOUND", x, y) - return [ null, 0 ] - } - - return [ nn, nd ] -} - -function find_enclosing_rect(list, x, y) { - for (let [x1, y1, x2, y2] of list) { - if (x >= x1 && x <= x2) - if (y >= y1 && y <= y2) - return true - } - return false -} - - -function make_spaces(points) { - let spaces = [] - for (let [x,y] of points) { - let [ name, dist ] = find_closest_node(labels, x, y) - if (dist > 50) console.log("DISTANCE TOO FAR", x, y, dist) - - spaces.push({ name: name.name, x, y }) - } - return spaces -} - -let data = {} - -data.spaces = make_spaces([ ...points.fortress, ...points.winter_quarters, ...points.space ]) - -console.log(data) - -function find_closest_point(x, y) { - let nd = Infinity, nn = -1 - - for (let i = 0; i < points.length; ++i) { - let n = points[i] - let d = Math.hypot(n.x - x, n.y - y) - if (d < nd) { - nd = d - nn = i +for (let group in boxes) { + for (let item of boxes[group]) { + if (item.name === null) { + item.name = find_label(item.x+item.w/2, item.y+item.w/2, 72) } } - - return nn } -// FIND and label all points! -let all_labels = labels.slice() -let cities = [] -for (let key in points) { - for (let [x, y] of points[key]) { - let [ node, dist ] = find_closest_node(labels, x, y) - if (dist > 15) { - console.log("DISTANCE TOO FAR", key,x,y, "dist=" + dist, "name=" + node.name) - } - if (node) { - labels = labels.filter(x => x !== node) - let suit = "UNKNOWN" - - if (find_enclosing_rect(rects.$CLUBS, x, y)) - suit = CLUBS - else if (find_enclosing_rect(rects.$HEARTS, x, y)) - suit = HEARTS - else if (find_enclosing_rect(rects.$DIAMONDS, x, y)) - suit = DIAMONDS - else if (find_enclosing_rect(rects.$SPADES, x, y)) - suit = SPADES - else - console.log("NOT ASSIGNED SUIT", x, y) - - let country = "UNKNOWN" - if (find_enclosing_rect(rects.$Empire, x, y)) { - country = EMPIRE - } - else if (find_enclosing_rect(rects.$Austria, x, y)) { - country = AUSTRIA - } - else if (find_enclosing_rect(rects.$Hanover, x, y)) { - country = HANOVER - } - else if (find_enclosing_rect(rects.$Saxony, x, y)) { - country = SAXONY - } - else if (find_enclosing_rect(rects.$Sweden, x, y)) { - country = SWEDEN - } - else if (find_enclosing_rect(rects.$Poland, x, y)) { - country = POLAND - } - else if (find_enclosing_rect(rects.$Prussia, x, y)) { - country = PRUSSIA - } - - if (country === "UNKNOWN") - console.log("no country:", node) - - cities.push({ - name: node.name, - country, - suit, - type: key, - x: Math.round(x), - y: Math.round(y), - adjacent: [], - major_roads: [], - roads: [], - }) - } else { - let [ dupname, dupdist ] = find_closest_node(all_labels, x, y) - console.log("ALREADY USED", dupname, dupdist, x, y) - } +for (let group in edges) { + for (let item of edges[group]) { + item.name1 = find_label(item.x1, item.y1, 72) + item.name2 = find_label(item.x2, item.y2, 72) } } -for (let e of edges.major_road) { - let a = find_closest_point(e.x1, e.y1) - let b = find_closest_point(e.x2, e.y2) - set_add(cities[a].major_roads, b) - set_add(cities[b].major_roads, a) - set_add(cities[a].adjacent, b) - set_add(cities[b].adjacent, a) -} - -for (let e of edges.road) { - let a = find_closest_point(e.x1, e.y1) - let b = find_closest_point(e.x2, e.y2) - set_add(cities[a].roads, b) - set_add(cities[b].roads, a) - set_add(cities[a].adjacent, b) - set_add(cities[b].adjacent, a) -} - -console.log("if (typeof module === 'object') module.exports = data") -*/ +fs.writeFileSync("tools/layout.json", JSON.stringify({boxes,points,edges,labels}, null, 4)) |