summaryrefslogtreecommitdiff
path: root/tools/parse-layout.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/parse-layout.js')
-rw-r--r--tools/parse-layout.js325
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))