svgmapviewer-tools-floors 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/inkscape/extensions/Attic/fix_guides.inx +17 -0
- package/inkscape/extensions/Attic/fix_guides.py +30 -0
- package/inkscape/extensions/Attic/fix_symbol_links.inx +17 -0
- package/inkscape/extensions/Attic/fix_symbol_links.py +71 -0
- package/inkscape/extensions/Attic/flatten_style.inx +17 -0
- package/inkscape/extensions/Attic/flatten_style.py +31 -0
- package/inkscape/extensions/Attic/load_markers.inx +17 -0
- package/inkscape/extensions/Attic/load_markers.py +117 -0
- package/inkscape/extensions/Attic/load_patterns.inx +17 -0
- package/inkscape/extensions/Attic/load_patterns.py +116 -0
- package/inkscape/extensions/Attic/load_symbols.inx +17 -0
- package/inkscape/extensions/Attic/load_symbols.py +164 -0
- package/inkscape/extensions/Attic/renumber_tree.inx +24 -0
- package/inkscape/extensions/Attic/renumber_tree.py +39 -0
- package/inkscape/extensions/Attic/repeat_path.inx +17 -0
- package/inkscape/extensions/Attic/repeat_path.py +58 -0
- package/inkscape/extensions/Attic/resolve_facility_links.inx +19 -0
- package/inkscape/extensions/Attic/resolve_facility_links.py +16 -0
- package/inkscape/extensions/Attic/sort_symbols.inx +17 -0
- package/inkscape/extensions/Attic/sort_symbols.py +48 -0
- package/inkscape/extensions/Attic/symbol_load.inx +17 -0
- package/inkscape/extensions/Attic/symbol_load.py +99 -0
- package/inkscape/extensions/Attic/tidy_tree.inx +22 -0
- package/inkscape/extensions/Attic/tidy_tree.py +178 -0
- package/inkscape/extensions/Attic/use_shop.inx +22 -0
- package/inkscape/extensions/Attic/use_shop.py +26 -0
- package/inkscape/extensions/README.md +34 -0
- package/inkscape/extensions/daijimaps/__init__.py +72 -0
- package/inkscape/extensions/daijimaps/address_tree.py +231 -0
- package/inkscape/extensions/daijimaps/common.py +49 -0
- package/inkscape/extensions/daijimaps/generate_addresses.py +41 -0
- package/inkscape/extensions/daijimaps/guards.py +47 -0
- package/inkscape/extensions/daijimaps/map_layer.py +47 -0
- package/inkscape/extensions/daijimaps/name.py +167 -0
- package/inkscape/extensions/daijimaps/renumber.py +38 -0
- package/inkscape/extensions/daijimaps/resolve_labels.py +65 -0
- package/inkscape/extensions/daijimaps/resolve_names.py +170 -0
- package/inkscape/extensions/daijimaps/save_addresses.py +274 -0
- package/inkscape/extensions/daijimaps/types.py +128 -0
- package/inkscape/extensions/daijimaps/visit_parents.py +37 -0
- package/inkscape/extensions/extract_labels.py +79 -0
- package/inkscape/extensions/fixup_floor_svg.py +28 -0
- package/inkscape/extensions/fixup_texts.inx +15 -0
- package/inkscape/extensions/fixup_texts.py +110 -0
- package/inkscape/extensions/fixup_tree.inx +15 -0
- package/inkscape/extensions/fixup_tree.py +17 -0
- package/inkscape/extensions/flatten_transform.inx +17 -0
- package/inkscape/extensions/flatten_transform.py +63 -0
- package/inkscape/extensions/import_labels.inx +20 -0
- package/inkscape/extensions/import_labels.py +52 -0
- package/inkscape/extensions/import_shops.inx +20 -0
- package/inkscape/extensions/import_shops.py +47 -0
- package/inkscape/extensions/install.sh +14 -0
- package/inkscape/extensions/load_shops.inx +20 -0
- package/inkscape/extensions/load_shops.py +86 -0
- package/inkscape/extensions/renumber_group.inx +15 -0
- package/inkscape/extensions/renumber_group.py +17 -0
- package/inkscape/extensions/resolve_labels.inx +20 -0
- package/inkscape/extensions/resolve_labels.py +142 -0
- package/inkscape/extensions/resolve_shops.inx +20 -0
- package/inkscape/extensions/resolve_shops.py +73 -0
- package/inkscape/extensions/unresolve_labels.inx +20 -0
- package/inkscape/extensions/unresolve_labels.py +53 -0
- package/inkscape/extensions/unresolve_shops.inx +20 -0
- package/inkscape/extensions/unresolve_shops.py +56 -0
- package/inkscape/templates/floors.svg +665 -0
- package/map-extract-floors.js +821 -0
- package/package.json +19 -0
- package/pyproject.toml +20 -0
- package/scripts/inkex-inkscape +14 -0
- package/scripts/inkex-python +14 -0
- package/scripts/inkex-setup +6 -0
- package/scripts/labels.sh +18 -0
- package/scripts/regen.py +77 -0
- package/scripts/regen.sh +24 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Daiji Maps
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Fix Guides</name>
|
|
4
|
+
<id>daijimaps.fix_guides</id>
|
|
5
|
+
<label>Fix guides</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Fixup" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">fix_guides.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FixGuides(inkex.EffectExtension):
|
|
8
|
+
def _show_guide(self, guide):
|
|
9
|
+
self.msg(
|
|
10
|
+
"guide:"
|
|
11
|
+
+ f" id={guide.get('id')}"
|
|
12
|
+
+ f" position={guide.raw_position}"
|
|
13
|
+
+ f" orientation={guide.orientation}"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def _do_guide(self, guide):
|
|
17
|
+
# self._show_guide(guide)
|
|
18
|
+
p = guide.raw_position
|
|
19
|
+
h = self.svg.viewbox_height
|
|
20
|
+
x = p[0]
|
|
21
|
+
y = h - p[1]
|
|
22
|
+
guide.set_position(x, y, guide.orientation)
|
|
23
|
+
|
|
24
|
+
def effect(self):
|
|
25
|
+
for guide in self.svg.namedview.get_guides():
|
|
26
|
+
self._do_guide(guide)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
FixGuides().run()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Fix Symbol Links</name>
|
|
4
|
+
<id>daijimaps.fix_symbol_links</id>
|
|
5
|
+
<label>Fix symbol links (href) under Content/Facilities</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Fixup" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">fix_symbol_links.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
|
|
6
|
+
import daijimaps
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FixSymbolLinks(daijimaps.AddressTree):
|
|
10
|
+
# XXX Find Content/Facilities
|
|
11
|
+
# XXX Find Toilets
|
|
12
|
+
# XXX Iterate children
|
|
13
|
+
# XXX Check if child has transform="translate()"
|
|
14
|
+
# XXX Check if child is <use/> or <g>
|
|
15
|
+
# XXX If not correct, regen <use/> with the correct href
|
|
16
|
+
|
|
17
|
+
def _make_use(self, kind, target):
|
|
18
|
+
x = inkex.Use()
|
|
19
|
+
x.label = target.label
|
|
20
|
+
x.attrib["href"] = f"X{kind}"
|
|
21
|
+
x.attrib["transform"] = target.atrib["transform"]
|
|
22
|
+
return x
|
|
23
|
+
|
|
24
|
+
def _is_good_use(self, child, kind):
|
|
25
|
+
if isinstance(child, inkex.Use):
|
|
26
|
+
if "transform" in child.attrib:
|
|
27
|
+
if "href" in child.attrib:
|
|
28
|
+
if child.attrib["href"] == f"X{kind}":
|
|
29
|
+
return True
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
def _find_group(self, layer, label) -> inkex.Group | None:
|
|
33
|
+
for child in list(layer):
|
|
34
|
+
if not isinstance(child, inkex.Group):
|
|
35
|
+
continue
|
|
36
|
+
if child.label is None or child.label != label:
|
|
37
|
+
continue
|
|
38
|
+
return child
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
def _process_addresses(self, node):
|
|
42
|
+
content: inkex.Group | None = self._find_group(node, "Content")
|
|
43
|
+
if content is None:
|
|
44
|
+
return False
|
|
45
|
+
facilities: inkex.Group | None = self._find_group(content, "Facilities")
|
|
46
|
+
if facilities is None:
|
|
47
|
+
return False
|
|
48
|
+
for facility in list(facilities):
|
|
49
|
+
if not isinstance(facility, inkex.Group):
|
|
50
|
+
continue
|
|
51
|
+
# e.g. kind == Toilets
|
|
52
|
+
kind = facility.label
|
|
53
|
+
if kind is None:
|
|
54
|
+
continue
|
|
55
|
+
if self.svg.getElementById(f"X{kind}") is None:
|
|
56
|
+
self.msg(f"unknown facility kind: {kind}")
|
|
57
|
+
continue
|
|
58
|
+
for child in list(facility):
|
|
59
|
+
# XXX style => attribute
|
|
60
|
+
if self._is_good_use(child, kind):
|
|
61
|
+
# good - nothing to do
|
|
62
|
+
continue
|
|
63
|
+
# fixup
|
|
64
|
+
self.msg(f"fixup use: {facility}: {kind}")
|
|
65
|
+
x = self._make_use(kind, child)
|
|
66
|
+
facility.remove(child)
|
|
67
|
+
facility.append(x)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
FixSymbolLinks().run()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Flatten Style</name>
|
|
4
|
+
<id>daijimaps.flatten_style</id>
|
|
5
|
+
<label>Flatteen tree by merging styles into leaves.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Fixup" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">flatten_style.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
group_styles = {"display"}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FlattenStyle(inkex.EffectExtension):
|
|
11
|
+
def _flatten_style(self, node):
|
|
12
|
+
if isinstance(node, inkex.Group):
|
|
13
|
+
ss = {}
|
|
14
|
+
for y in group_styles:
|
|
15
|
+
if y in node.style:
|
|
16
|
+
ss[y] = node.style[y]
|
|
17
|
+
for child in list(node):
|
|
18
|
+
child.style.add_inherited(node.style)
|
|
19
|
+
node.style = ss
|
|
20
|
+
for child in list(node):
|
|
21
|
+
self._flatten_style(child)
|
|
22
|
+
return True
|
|
23
|
+
|
|
24
|
+
def effect(self):
|
|
25
|
+
if self.svg.selection:
|
|
26
|
+
for node in self.svg.selection.values():
|
|
27
|
+
self._flatten_style(node)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if __name__ == "__main__":
|
|
31
|
+
FlattenStyle().run()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Load Markers</name>
|
|
4
|
+
<id>daijimaps.load_markers</id>
|
|
5
|
+
<label>Load markers under Assets.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Assets" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">load_markers.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import copy
|
|
5
|
+
import csv
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
import inkex
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LoadMarkers(inkex.EffectExtension):
|
|
13
|
+
# (Assets)/(Markers)
|
|
14
|
+
_assets = None
|
|
15
|
+
_markers = None
|
|
16
|
+
_markers_csv = None
|
|
17
|
+
|
|
18
|
+
def _find_group(self, group):
|
|
19
|
+
assert isinstance(self._markers, inkex.Group)
|
|
20
|
+
for node in list(self._markers):
|
|
21
|
+
if node.label == group:
|
|
22
|
+
return node
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
def _install_marker(self, v, node):
|
|
26
|
+
g = inkex.Group()
|
|
27
|
+
g.label = v["name"] # 'Triangle'
|
|
28
|
+
g.append(node)
|
|
29
|
+
prev = None
|
|
30
|
+
assert isinstance(self._markers, inkex.Group)
|
|
31
|
+
for node in list(self._markers):
|
|
32
|
+
if node.label == v["name"]:
|
|
33
|
+
prev = node
|
|
34
|
+
if prev is not None:
|
|
35
|
+
self._markers.remove(prev)
|
|
36
|
+
self._markers.append(g)
|
|
37
|
+
node.set("id", v["name"]) # 'Triangle'
|
|
38
|
+
return True
|
|
39
|
+
|
|
40
|
+
def _load_marker(self, v):
|
|
41
|
+
svg_path = self.svg_path()
|
|
42
|
+
assert isinstance(svg_path, str)
|
|
43
|
+
file = os.path.join(svg_path, v["file"])
|
|
44
|
+
f = inkex.load_svg(file)
|
|
45
|
+
r = f.getroot()
|
|
46
|
+
assert isinstance(r, inkex.SvgDocumentElement)
|
|
47
|
+
node = r.getElementById(v["id"])
|
|
48
|
+
return copy.deepcopy(node)
|
|
49
|
+
|
|
50
|
+
def _handle_entry(self, v):
|
|
51
|
+
# name,file,id
|
|
52
|
+
if v["name"] == "":
|
|
53
|
+
return False
|
|
54
|
+
self.msg(f"- {v['name']}")
|
|
55
|
+
if re.match("^#.*$", v["name"]) is not None:
|
|
56
|
+
return False
|
|
57
|
+
node = self._load_marker(v)
|
|
58
|
+
if node is None:
|
|
59
|
+
return False
|
|
60
|
+
self._install_marker(v, node)
|
|
61
|
+
return True
|
|
62
|
+
|
|
63
|
+
def _parse_markers_csv(self):
|
|
64
|
+
svg_path = self.svg_path()
|
|
65
|
+
assert isinstance(svg_path, str)
|
|
66
|
+
self._markers_csv = os.path.join(svg_path, "markers.csv")
|
|
67
|
+
with open(self._markers_csv, "r", encoding="utf-8") as fh:
|
|
68
|
+
reader = csv.DictReader(fh)
|
|
69
|
+
values = [line for line in reader]
|
|
70
|
+
for v in values:
|
|
71
|
+
self._handle_entry(v)
|
|
72
|
+
|
|
73
|
+
def _find_assets_markers(self):
|
|
74
|
+
assert isinstance(self._assets, inkex.Group)
|
|
75
|
+
for child in list(self._assets):
|
|
76
|
+
if isinstance(child, inkex.Group) and child.label == "(Markers)":
|
|
77
|
+
self._markers = child
|
|
78
|
+
|
|
79
|
+
def _find_assets(self):
|
|
80
|
+
assert isinstance(self.document, inkex.SvgDocumentElement)
|
|
81
|
+
res = [
|
|
82
|
+
node
|
|
83
|
+
for node in self.document.getroot()
|
|
84
|
+
if isinstance(node, inkex.Group)
|
|
85
|
+
if isinstance(node.label, str)
|
|
86
|
+
if re.match("^[(]Assets[)]$", node.label) is not None
|
|
87
|
+
]
|
|
88
|
+
if len(res) != 1:
|
|
89
|
+
return None
|
|
90
|
+
else:
|
|
91
|
+
return res[0]
|
|
92
|
+
|
|
93
|
+
def _load_markers(self):
|
|
94
|
+
self.msg("=== load markers: start")
|
|
95
|
+
self._assets = self._find_assets()
|
|
96
|
+
if self._assets is None:
|
|
97
|
+
self.msg("(Assets) not found!")
|
|
98
|
+
return False
|
|
99
|
+
self._find_assets_markers()
|
|
100
|
+
if self._markers is None:
|
|
101
|
+
self.msg("(Assets)/(Markers) not found!")
|
|
102
|
+
return False
|
|
103
|
+
self._parse_markers_csv()
|
|
104
|
+
self.msg("=== load markers: end")
|
|
105
|
+
|
|
106
|
+
def _remove_defs_markers(self):
|
|
107
|
+
for child in list(self.svg.defs):
|
|
108
|
+
if isinstance(child, inkex.Marker):
|
|
109
|
+
self.svg.defs.remove(child)
|
|
110
|
+
|
|
111
|
+
def effect(self):
|
|
112
|
+
self._remove_defs_markers()
|
|
113
|
+
self._load_markers()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
LoadMarkers().run()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Load Patterns</name>
|
|
4
|
+
<id>daijimaps.load_patterns</id>
|
|
5
|
+
<label>Load patterns under Assets.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Assets" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">load_patterns.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import copy
|
|
5
|
+
import csv
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from lxml import etree
|
|
10
|
+
|
|
11
|
+
import inkex
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class LoadPatterns(inkex.EffectExtension):
|
|
15
|
+
# (Assets)/(Patterns)
|
|
16
|
+
_assets = None
|
|
17
|
+
_patterns = None
|
|
18
|
+
_patterns_csv = None
|
|
19
|
+
|
|
20
|
+
def _find_group(self, group):
|
|
21
|
+
assert isinstance(self._patterns, inkex.Group)
|
|
22
|
+
for node in list(self._patterns):
|
|
23
|
+
if node.label == group:
|
|
24
|
+
return node
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
def _install_pattern(self, v, node):
|
|
28
|
+
prev = None
|
|
29
|
+
assert isinstance(self._patterns, inkex.Group)
|
|
30
|
+
for child in list(self._patterns):
|
|
31
|
+
if child.get("id") == v["name"]:
|
|
32
|
+
prev = child
|
|
33
|
+
if prev is not None:
|
|
34
|
+
self._patterns.remove(prev)
|
|
35
|
+
self._patterns.append(node)
|
|
36
|
+
node.set("id", v["name"]) # 'StairsH'
|
|
37
|
+
return True
|
|
38
|
+
|
|
39
|
+
def _load_pattern(self, v):
|
|
40
|
+
svg_path = self.svg_path()
|
|
41
|
+
assert isinstance(svg_path, str)
|
|
42
|
+
file = os.path.join(svg_path, v["file"])
|
|
43
|
+
f = inkex.load_svg(file)
|
|
44
|
+
r = f.getroot()
|
|
45
|
+
assert isinstance(r, inkex.SvgDocumentElement)
|
|
46
|
+
node = r.getElementById(v["id"])
|
|
47
|
+
return copy.deepcopy(node)
|
|
48
|
+
|
|
49
|
+
def _handle_entry(self, v):
|
|
50
|
+
# name,file,id
|
|
51
|
+
if v["name"] == "":
|
|
52
|
+
return False
|
|
53
|
+
self.msg(f"- {v['name']}")
|
|
54
|
+
if re.match("^#.*$", v["name"]) is not None:
|
|
55
|
+
return False
|
|
56
|
+
node = self._load_pattern(v)
|
|
57
|
+
if node is None:
|
|
58
|
+
return False
|
|
59
|
+
self._install_pattern(v, node)
|
|
60
|
+
return True
|
|
61
|
+
|
|
62
|
+
def _parse_patterns_csv(self):
|
|
63
|
+
svg_path = self.svg_path()
|
|
64
|
+
assert isinstance(svg_path, str)
|
|
65
|
+
self._patterns_csv = os.path.join(svg_path, "patterns.csv")
|
|
66
|
+
with open(self._patterns_csv, "r", encoding="utf-8") as fh:
|
|
67
|
+
reader = csv.DictReader(fh)
|
|
68
|
+
values = [line for line in reader]
|
|
69
|
+
for v in values:
|
|
70
|
+
self._handle_entry(v)
|
|
71
|
+
|
|
72
|
+
def _find_assets_patterns(self):
|
|
73
|
+
assert isinstance(self._assets, inkex.Group)
|
|
74
|
+
for child in list(self._assets):
|
|
75
|
+
if isinstance(child, inkex.Group) and child.label == "(Patterns)":
|
|
76
|
+
self._patterns = child
|
|
77
|
+
|
|
78
|
+
def _find_assets(self):
|
|
79
|
+
assert isinstance(self.document, etree._ElementTree)
|
|
80
|
+
res = [
|
|
81
|
+
node
|
|
82
|
+
for node in self.document.getroot()
|
|
83
|
+
if isinstance(node, inkex.Group)
|
|
84
|
+
if isinstance(node.label, str)
|
|
85
|
+
if re.match("^[(]Assets[)]$", node.label) is not None
|
|
86
|
+
]
|
|
87
|
+
if len(res) != 1:
|
|
88
|
+
return None
|
|
89
|
+
else:
|
|
90
|
+
return res[0]
|
|
91
|
+
|
|
92
|
+
def _load_patterns(self):
|
|
93
|
+
self.msg("=== load patterns: start")
|
|
94
|
+
self._assets = self._find_assets()
|
|
95
|
+
if self._assets is None:
|
|
96
|
+
self.msg("(Assets) not found!")
|
|
97
|
+
return False
|
|
98
|
+
self._find_assets_patterns()
|
|
99
|
+
if self._patterns is None:
|
|
100
|
+
self.msg("(Assets)/(Patterns) not found!")
|
|
101
|
+
return False
|
|
102
|
+
self._parse_patterns_csv()
|
|
103
|
+
self.msg("=== load patterns: end")
|
|
104
|
+
|
|
105
|
+
def _remove_defs_patterns(self):
|
|
106
|
+
for child in list(self.svg.defs):
|
|
107
|
+
if isinstance(child, inkex.Pattern):
|
|
108
|
+
self.svg.defs.remove(child)
|
|
109
|
+
|
|
110
|
+
def effect(self):
|
|
111
|
+
self._remove_defs_patterns()
|
|
112
|
+
self._load_patterns()
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
LoadPatterns().run()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Load Symbols</name>
|
|
4
|
+
<id>daijimaps.load_symbols</id>
|
|
5
|
+
<label>Load symbols under Assets.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Assets" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">load_symbols.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import csv
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
from lxml import etree
|
|
9
|
+
|
|
10
|
+
import inkex
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LoadSymbols(inkex.EffectExtension):
|
|
14
|
+
# (Assets)/(Symbols)
|
|
15
|
+
_assets = None
|
|
16
|
+
_symbols = None
|
|
17
|
+
_symbols_csv = None
|
|
18
|
+
|
|
19
|
+
def _find_group(self, group):
|
|
20
|
+
assert isinstance(self._symbols, inkex.Group)
|
|
21
|
+
for node in list(self._symbols):
|
|
22
|
+
if node.label == group:
|
|
23
|
+
return node
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
def _install_symbol(self, v, node):
|
|
27
|
+
g = self._find_group(v["group"])
|
|
28
|
+
assert isinstance(self._symbols, inkex.Group)
|
|
29
|
+
if g is None:
|
|
30
|
+
g = inkex.Group()
|
|
31
|
+
g.label = v["group"] # '(Facilities)'
|
|
32
|
+
self._symbols.append(g)
|
|
33
|
+
s = inkex.Group()
|
|
34
|
+
s.label = v["name"] # 'Toilets'
|
|
35
|
+
x = inkex.Group()
|
|
36
|
+
x.label = "X" + v["name"] # 'XToilets'
|
|
37
|
+
x.set("id", x.label) # 'XToilets'
|
|
38
|
+
x.set("transform", f"scale({v['scale']}) translate({v['dx']}, {v['dy']})")
|
|
39
|
+
for c in list(node):
|
|
40
|
+
x.append(c)
|
|
41
|
+
s.append(x)
|
|
42
|
+
prev = None
|
|
43
|
+
for node in list(g):
|
|
44
|
+
if node.label == v["name"]:
|
|
45
|
+
prev = node
|
|
46
|
+
g.append(s)
|
|
47
|
+
if prev is not None:
|
|
48
|
+
g.remove(prev)
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
# AigaSymbols.svg#Elevator_Inv defines '#person2' (and uses it)
|
|
52
|
+
# Rename '#person2' to '#_person2' so it will not be trimmed
|
|
53
|
+
# by map-extract-floors.py:fixupElement()
|
|
54
|
+
def _fixup_symbol_ids(self, tree):
|
|
55
|
+
if tree is None:
|
|
56
|
+
return
|
|
57
|
+
href_ids = {}
|
|
58
|
+
for e in tree.iter():
|
|
59
|
+
href = e.get("href") or e.get("xlink:href")
|
|
60
|
+
if href is not None:
|
|
61
|
+
href_id = re.sub(r"#", "", href)
|
|
62
|
+
href_ids[href_id] = True
|
|
63
|
+
for e in tree.iter():
|
|
64
|
+
_id = e.get("id")
|
|
65
|
+
if _id in href_ids:
|
|
66
|
+
self.msg(f"fixing id: {_id} -> _{_id}")
|
|
67
|
+
e.set("id", f"_{_id}")
|
|
68
|
+
href = e.get("xlink:href")
|
|
69
|
+
if href is not None:
|
|
70
|
+
href_id = re.sub(r"#", "", href)
|
|
71
|
+
if href_id in href_ids:
|
|
72
|
+
self.msg(f"fixing href: #{href_id} -> #_{href_id}")
|
|
73
|
+
e.set("xlink:href", f"#_{href_id}")
|
|
74
|
+
|
|
75
|
+
def _fixup_symbol_titles(self, node):
|
|
76
|
+
if node is None:
|
|
77
|
+
return
|
|
78
|
+
for e in node.iter():
|
|
79
|
+
if isinstance(e.tag, str) and re.match("^.*title.*$", e.tag) is not None:
|
|
80
|
+
self.msg(f"deleting title: {e}")
|
|
81
|
+
p = e.getparent()
|
|
82
|
+
p.remove(e)
|
|
83
|
+
elif isinstance(e, etree._Comment):
|
|
84
|
+
self.msg(f"deleting comment: {e}")
|
|
85
|
+
p = e.getparent()
|
|
86
|
+
if p:
|
|
87
|
+
p.remove(e)
|
|
88
|
+
|
|
89
|
+
def _fixup_symbol(self, node):
|
|
90
|
+
self._fixup_symbol_ids(node)
|
|
91
|
+
self._fixup_symbol_titles(node)
|
|
92
|
+
|
|
93
|
+
def _load_symbol(self, v):
|
|
94
|
+
svg_path = self.svg_path()
|
|
95
|
+
assert isinstance(svg_path, str)
|
|
96
|
+
file = os.path.join(svg_path, v["file"])
|
|
97
|
+
f = inkex.load_svg(file)
|
|
98
|
+
r = f.getroot()
|
|
99
|
+
assert isinstance(r, inkex.SvgDocumentElement)
|
|
100
|
+
node = r.getElementById(v["id"])
|
|
101
|
+
self._fixup_symbol(node)
|
|
102
|
+
return node
|
|
103
|
+
|
|
104
|
+
def _handle_entry(self, v):
|
|
105
|
+
# group,name,file,id,dx,dy,scale
|
|
106
|
+
if v["group"] == "":
|
|
107
|
+
return False
|
|
108
|
+
if re.match("^#.*$", v["group"]) is not None:
|
|
109
|
+
return False
|
|
110
|
+
node = self._load_symbol(v)
|
|
111
|
+
if node is None:
|
|
112
|
+
self.msg(f"symbol not found: {v}")
|
|
113
|
+
return False
|
|
114
|
+
self._install_symbol(v, node)
|
|
115
|
+
return True
|
|
116
|
+
|
|
117
|
+
def _parse_symbols_csv(self):
|
|
118
|
+
svg_path = self.svg_path()
|
|
119
|
+
assert isinstance(svg_path, str)
|
|
120
|
+
self._symbols_csv = os.path.join(svg_path, "symbols.csv")
|
|
121
|
+
with open(self._symbols_csv, "r", encoding="utf-8") as fh:
|
|
122
|
+
reader = csv.DictReader(fh)
|
|
123
|
+
_header = next(reader)
|
|
124
|
+
values = [line for line in reader]
|
|
125
|
+
for v in values:
|
|
126
|
+
self._handle_entry(v)
|
|
127
|
+
|
|
128
|
+
def _find_assets_symbols(self):
|
|
129
|
+
assert isinstance(self._assets, inkex.Group)
|
|
130
|
+
for child in list(self._assets):
|
|
131
|
+
if isinstance(child, inkex.Group) and child.label == "(Symbols)":
|
|
132
|
+
self._symbols = child
|
|
133
|
+
|
|
134
|
+
def _find_assets(self):
|
|
135
|
+
assert isinstance(self.document, etree._ElementTree)
|
|
136
|
+
res = [
|
|
137
|
+
node
|
|
138
|
+
for node in self.document.getroot()
|
|
139
|
+
if isinstance(node, inkex.Group)
|
|
140
|
+
if isinstance(node.label, str)
|
|
141
|
+
if re.match("^[(]Assets[)]$", node.label) is not None
|
|
142
|
+
]
|
|
143
|
+
if len(res) != 1:
|
|
144
|
+
return None
|
|
145
|
+
else:
|
|
146
|
+
return res[0]
|
|
147
|
+
|
|
148
|
+
def _load_symbols(self):
|
|
149
|
+
self.msg("=== load symbols: start")
|
|
150
|
+
self._assets = self._find_assets()
|
|
151
|
+
if self._assets is None:
|
|
152
|
+
return False
|
|
153
|
+
self._find_assets_symbols()
|
|
154
|
+
if self._symbols is None:
|
|
155
|
+
return False
|
|
156
|
+
self._parse_symbols_csv()
|
|
157
|
+
self.msg("=== load symbols: end")
|
|
158
|
+
|
|
159
|
+
def effect(self):
|
|
160
|
+
self._load_symbols()
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == "__main__":
|
|
164
|
+
LoadSymbols().run()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Renumber (Tree)</name>
|
|
4
|
+
<id>daijimaps.renumber_tree</id>
|
|
5
|
+
<label>Renumber groups under the selected tree.</label>
|
|
6
|
+
<param name="tab" type="notebook">
|
|
7
|
+
<page name="Options" gui-text="Options">
|
|
8
|
+
<param name="floor" type="string" gui-text="Target floor (regular expression)">.</param>
|
|
9
|
+
</page>
|
|
10
|
+
</param>
|
|
11
|
+
<effect needs-live-preview="false">
|
|
12
|
+
<object-type>all</object-type>
|
|
13
|
+
<effects-menu>
|
|
14
|
+
<submenu name="Daiji Maps">
|
|
15
|
+
<submenu name="Addressess">
|
|
16
|
+
<submenu name="Renumber" />
|
|
17
|
+
</submenu>
|
|
18
|
+
</submenu>
|
|
19
|
+
</effects-menu>
|
|
20
|
+
</effect>
|
|
21
|
+
<script>
|
|
22
|
+
<command location="inx" interpreter="python">renumber_tree.py</command>
|
|
23
|
+
</script>
|
|
24
|
+
</inkscape-extension>
|