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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
import daijimaps
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RenumberTree(daijimaps.AddressTree):
|
|
10
|
+
def _is_anonymous(self, node):
|
|
11
|
+
# - no label
|
|
12
|
+
# - or label NOT starting with [A-Z]
|
|
13
|
+
if node.label is None:
|
|
14
|
+
return True
|
|
15
|
+
return re.match("^[A-Z]", node.label) is None
|
|
16
|
+
|
|
17
|
+
def _check_children(self, node):
|
|
18
|
+
# All children should be anonymous (renumber-able)
|
|
19
|
+
for child in list(node):
|
|
20
|
+
if child.label and self._ignoring(child):
|
|
21
|
+
return False
|
|
22
|
+
if not self._is_anonymous(child):
|
|
23
|
+
return False
|
|
24
|
+
return True
|
|
25
|
+
|
|
26
|
+
def _visitor_node_branch_renumber(self, node, parents):
|
|
27
|
+
renumbering = self._check_children(node)
|
|
28
|
+
if renumbering:
|
|
29
|
+
daijimaps.renumber_group(node)
|
|
30
|
+
|
|
31
|
+
def _visitor_node_branch(self, node, parents):
|
|
32
|
+
self._visitor_node_branch_renumber(node, parents)
|
|
33
|
+
|
|
34
|
+
def effect(self):
|
|
35
|
+
super().effect()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
RenumberTree().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>Repeat path</name>
|
|
4
|
+
<id>daijimaps.repeat_path</id>
|
|
5
|
+
<label>Repeat path.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Path" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">repeat_path.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def repeat_path_path(p: inkex.Path):
|
|
8
|
+
xs = list(p.control_points)
|
|
9
|
+
if len(xs) != 4:
|
|
10
|
+
return None
|
|
11
|
+
o = xs[0]
|
|
12
|
+
v1 = xs[1] - o
|
|
13
|
+
v2 = xs[2] - o
|
|
14
|
+
v3 = xs[3] - o
|
|
15
|
+
# checks
|
|
16
|
+
if v1.dot(v2) != 0:
|
|
17
|
+
return None
|
|
18
|
+
if v2.cross(v3) != 0:
|
|
19
|
+
return None
|
|
20
|
+
d = -v1 + v2
|
|
21
|
+
c = inkex.Vector2d()
|
|
22
|
+
pp = inkex.Path()
|
|
23
|
+
pp.append(inkex.paths.Move(o.x, o.y))
|
|
24
|
+
while c.length < v3.length:
|
|
25
|
+
pp.append(inkex.paths.line(v1.x, v1.y))
|
|
26
|
+
pp.append(inkex.paths.move(d.x, d.y))
|
|
27
|
+
c = c + v2
|
|
28
|
+
pp.append(inkex.paths.line(v1.x, v1.y))
|
|
29
|
+
return pp
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def repeat_path(node: inkex.PathElement):
|
|
33
|
+
p = node.get_path().to_absolute()
|
|
34
|
+
pp = repeat_path_path(p)
|
|
35
|
+
if pp is None:
|
|
36
|
+
# self.msg(f"n points: {len(xs)}")
|
|
37
|
+
# self.msg(f"# of points must be 4!")
|
|
38
|
+
return False
|
|
39
|
+
else:
|
|
40
|
+
node.set_path(pp)
|
|
41
|
+
return True
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class RepeatPath(inkex.EffectExtension):
|
|
45
|
+
def _repeat_path(self, node):
|
|
46
|
+
if not isinstance(node, inkex.PathElement):
|
|
47
|
+
# self.msg(f"not a path element!")
|
|
48
|
+
return False
|
|
49
|
+
repeat_path(node)
|
|
50
|
+
|
|
51
|
+
def effect(self):
|
|
52
|
+
if self.svg.selection:
|
|
53
|
+
for node in self.svg.selection.values():
|
|
54
|
+
self._repeat_path(node)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
RepeatPath().run()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Resolve facility links</name>
|
|
4
|
+
<id>daijimaps.resolve_facility_links</id>
|
|
5
|
+
<label>Resolve facility links.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Addressess">
|
|
11
|
+
<submenu name="Resolve" />
|
|
12
|
+
</submenu>
|
|
13
|
+
</submenu>
|
|
14
|
+
</effects-menu>
|
|
15
|
+
</effect>
|
|
16
|
+
<script>
|
|
17
|
+
<command location="inx" interpreter="python">resolve_facility_links.py</command>
|
|
18
|
+
</script>
|
|
19
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import daijimaps
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ResolveFacilityLinks(daijimaps.SaveAddresses):
|
|
8
|
+
def _post_layers(self):
|
|
9
|
+
self.msg("=== resolve facility links: start")
|
|
10
|
+
self._collect_links()
|
|
11
|
+
self._save_links()
|
|
12
|
+
self.msg("=== resolve facility links: end")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
ResolveFacilityLinks().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>Sort Symbols</name>
|
|
4
|
+
<id>daijimaps.sort_symbols</id>
|
|
5
|
+
<label>Sort symbols.</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">sort_symbols.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
PER_ROW = 20
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SortSymbols(inkex.EffectExtension):
|
|
12
|
+
def _sort_symbols(self, node):
|
|
13
|
+
if not isinstance(node, inkex.Group):
|
|
14
|
+
return False
|
|
15
|
+
max_width = 0
|
|
16
|
+
max_height = 0
|
|
17
|
+
for child in list(node):
|
|
18
|
+
label = child.label
|
|
19
|
+
if not label:
|
|
20
|
+
return False
|
|
21
|
+
if not re.match("^[A-Z].*$", label):
|
|
22
|
+
return False
|
|
23
|
+
bb = child.shape_box()
|
|
24
|
+
if bb is None:
|
|
25
|
+
return False
|
|
26
|
+
size = bb.size
|
|
27
|
+
max_width = max(max_width, size.x)
|
|
28
|
+
max_height = max(max_height, size.y)
|
|
29
|
+
children = sorted(list(node), key=lambda e: e.label if e.label else "")
|
|
30
|
+
for child in children:
|
|
31
|
+
node.remove(child)
|
|
32
|
+
for i, child in enumerate(children):
|
|
33
|
+
x = i % PER_ROW
|
|
34
|
+
y = int(i / PER_ROW)
|
|
35
|
+
tx = x * max_width * 1.25
|
|
36
|
+
ty = y * max_height * 1.25
|
|
37
|
+
child.transform = inkex.Transform(f"translate({tx}, {ty})")
|
|
38
|
+
node.append(child)
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
def effect(self):
|
|
42
|
+
if self.svg.selection:
|
|
43
|
+
for node in self.svg.selection.values():
|
|
44
|
+
self._sort_symbols(node)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
SortSymbols().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>Symbol Load</name>
|
|
4
|
+
<id>daijimaps.symbol_load</id>
|
|
5
|
+
<label>Load a symbol into the defs section.</label>
|
|
6
|
+
<effect needs-live-preview="false">
|
|
7
|
+
<object-type>all</object-type>
|
|
8
|
+
<effects-menu>
|
|
9
|
+
<submenu name="Daiji Maps">
|
|
10
|
+
<submenu name="Symbol" />
|
|
11
|
+
</submenu>
|
|
12
|
+
</effects-menu>
|
|
13
|
+
</effect>
|
|
14
|
+
<script>
|
|
15
|
+
<command location="inx" interpreter="python">symbol_load.py</command>
|
|
16
|
+
</script>
|
|
17
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SymbolLoad(inkex.EffectExtension):
|
|
8
|
+
_symbol_name = ""
|
|
9
|
+
_symbol_content = None
|
|
10
|
+
_symbol_node = None
|
|
11
|
+
|
|
12
|
+
def _replace_symbol(self):
|
|
13
|
+
content = self._symbol_content
|
|
14
|
+
node = self._symbol_node
|
|
15
|
+
|
|
16
|
+
if not (content is not None and node is not None):
|
|
17
|
+
self.msg("Something is wrong!")
|
|
18
|
+
return False
|
|
19
|
+
|
|
20
|
+
self.msg(f"Loading the new symbol {self._symbol_name}!")
|
|
21
|
+
|
|
22
|
+
content.delete()
|
|
23
|
+
node.remove_all()
|
|
24
|
+
# XXX why node.add(list) does not work?
|
|
25
|
+
for c in list(content):
|
|
26
|
+
self.msg(f"appending {c}...")
|
|
27
|
+
node.append(c)
|
|
28
|
+
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
def _find_symbol_for_replace(self):
|
|
32
|
+
name = self._symbol_name
|
|
33
|
+
|
|
34
|
+
sym = self.svg.getElementById(f"#{name}")
|
|
35
|
+
if sym is None:
|
|
36
|
+
self.msg(f"Target <symbol> (#{name}) not found!")
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
if sym.tag_name != "symbol":
|
|
40
|
+
self.msg("Not a <symbol> tag!")
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
self._symbol_node = sym
|
|
44
|
+
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
def _check_group_for_replace(self, node):
|
|
48
|
+
if not isinstance(node, inkex.Group):
|
|
49
|
+
self.msg("Group must be selected!")
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
name = node.label
|
|
53
|
+
if name is None:
|
|
54
|
+
self.msg("Symbol name must be defined as label!")
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
children = list(node)
|
|
58
|
+
|
|
59
|
+
if len(children) != 2:
|
|
60
|
+
self.msg("Group must exactly contain <use> and <g>!")
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
orig = children[0]
|
|
64
|
+
|
|
65
|
+
if not isinstance(orig, inkex.Use):
|
|
66
|
+
self.msg("Group must exactly contain <use> and <g>!")
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
if not orig.href:
|
|
70
|
+
self.msg("no href found")
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
href = f"#{orig.href.get_id()}"
|
|
74
|
+
|
|
75
|
+
if href != f"#{name}":
|
|
76
|
+
self.msg(f"Group name ({name}) does not match <use> symbol name ({href})!")
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
content = children[1]
|
|
80
|
+
|
|
81
|
+
if not isinstance(content, inkex.Group):
|
|
82
|
+
self.msg("The target is not a Group!")
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
self._symbol_name = name
|
|
86
|
+
self._symbol_content = content
|
|
87
|
+
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
def effect(self):
|
|
91
|
+
if self.svg.selection:
|
|
92
|
+
for node in self.svg.selection.values():
|
|
93
|
+
if self._check_group_for_replace(node):
|
|
94
|
+
if self._find_symbol_for_replace():
|
|
95
|
+
self._replace_symbol()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if __name__ == "__main__":
|
|
99
|
+
SymbolLoad().run()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Tidy tree</name>
|
|
4
|
+
<id>daijimaps.tidy_tree</id>
|
|
5
|
+
<label>Tidy tree for Daiji Maps map SVG.</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="Tidy" />
|
|
16
|
+
</submenu>
|
|
17
|
+
</effects-menu>
|
|
18
|
+
</effect>
|
|
19
|
+
<script>
|
|
20
|
+
<command location="inx" interpreter="python">tidy_tree.py</command>
|
|
21
|
+
</script>
|
|
22
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
import inkex
|
|
5
|
+
import re
|
|
6
|
+
import daijimaps
|
|
7
|
+
import repeat_path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
attrib_styles = inkex.all_properties.keys()
|
|
11
|
+
|
|
12
|
+
group_styles = {"display"}
|
|
13
|
+
|
|
14
|
+
invalid_styles = {
|
|
15
|
+
"line-height",
|
|
16
|
+
"text-align",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TidyTree(daijimaps.AddressTree):
|
|
21
|
+
_find_layers_opts = {
|
|
22
|
+
# include '(Assets)'
|
|
23
|
+
"skip_ignoring": False
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def _fixup_style(self, node):
|
|
27
|
+
if "display" in node.style and node.style["display"] == "inline":
|
|
28
|
+
self.msg(f"fixing display: {node.label}")
|
|
29
|
+
del node.style["display"]
|
|
30
|
+
|
|
31
|
+
if "opacity" in node.style and node.style["opacity"] == "1":
|
|
32
|
+
self.msg(f"fixing opacity: {node.label}")
|
|
33
|
+
del node.style["opacity"]
|
|
34
|
+
|
|
35
|
+
for k, v in node.style.items():
|
|
36
|
+
if k not in group_styles:
|
|
37
|
+
self.msg(f"fixing {k}: {node.label}")
|
|
38
|
+
del node.style[k]
|
|
39
|
+
if re.match("^-.*$", k):
|
|
40
|
+
# skip -inkscape-font-specification
|
|
41
|
+
pass
|
|
42
|
+
else:
|
|
43
|
+
node.set(k, v)
|
|
44
|
+
|
|
45
|
+
def _fixup_attrib(self, node):
|
|
46
|
+
# clear attribs irrelevant for <g/>
|
|
47
|
+
if isinstance(node, inkex.Group):
|
|
48
|
+
for a in node.attrib:
|
|
49
|
+
if a in attrib_styles:
|
|
50
|
+
self.msg(f"del {a} from node {node.label}")
|
|
51
|
+
del node.attrib[a]
|
|
52
|
+
|
|
53
|
+
for a in node.attrib:
|
|
54
|
+
if a in invalid_styles:
|
|
55
|
+
self.msg(f"del {a} from node {node.label}")
|
|
56
|
+
del node.attrib[a]
|
|
57
|
+
|
|
58
|
+
def _fixup_path(self, node):
|
|
59
|
+
# pass
|
|
60
|
+
# has_stroke = True
|
|
61
|
+
# has_stroke_width = False
|
|
62
|
+
has_marker_start = False
|
|
63
|
+
has_marker_end = False
|
|
64
|
+
if not isinstance(node, inkex.PathElement):
|
|
65
|
+
return
|
|
66
|
+
for a in node.attrib:
|
|
67
|
+
# if a == "stroke" and node.attrib["stroke"] == "none":
|
|
68
|
+
# has_stroke = False
|
|
69
|
+
# if a == "stroke-width":
|
|
70
|
+
# has_stroke_width = True
|
|
71
|
+
if a == "marker-start":
|
|
72
|
+
has_marker_start = True
|
|
73
|
+
if a == "marker-end":
|
|
74
|
+
has_marker_end = True
|
|
75
|
+
# for k, v in node.style.items():
|
|
76
|
+
# if k == "stroke" and node.style["stroke"] == "none":
|
|
77
|
+
# has_stroke = False
|
|
78
|
+
# if k == "stroke-width":
|
|
79
|
+
# has_stroke_width = True
|
|
80
|
+
# if has_stroke and not has_stroke_width:
|
|
81
|
+
# self.msg(f"fixing stroke-width for {node.label}")
|
|
82
|
+
# node.attrib["stroke-width"] = "1"
|
|
83
|
+
if has_marker_start:
|
|
84
|
+
if node.attrib["marker-start"] != "url(#Triangle)":
|
|
85
|
+
self.msg(f"fixing marker-start for {node.label}")
|
|
86
|
+
node.attrib["marker-start"] = "url(#Triangle)"
|
|
87
|
+
if has_marker_end:
|
|
88
|
+
if node.attrib["marker-end"] != "url(#Triangle)":
|
|
89
|
+
self.msg(f"fixing marker-end for {node.label}")
|
|
90
|
+
node.attrib["marker-end"] = "url(#Triangle)"
|
|
91
|
+
# expand repeat path
|
|
92
|
+
if repeat_path.repeat_path(node):
|
|
93
|
+
self.msg(f"expanding repeat path for {node.label}")
|
|
94
|
+
|
|
95
|
+
def _sort_children(self, node):
|
|
96
|
+
children = {}
|
|
97
|
+
for a in list(node):
|
|
98
|
+
if a.label:
|
|
99
|
+
node.remove(a)
|
|
100
|
+
# a.label looks like: "Sov. @ A4F-Shops-1-3"
|
|
101
|
+
if a.label not in children:
|
|
102
|
+
children[a.label] = []
|
|
103
|
+
children[a.label].append(a)
|
|
104
|
+
# assume alphabetical order
|
|
105
|
+
labels = sorted(children.keys(), key=lambda label: str.lower(label))
|
|
106
|
+
for label in labels:
|
|
107
|
+
for a in children[label]:
|
|
108
|
+
node.append(a)
|
|
109
|
+
|
|
110
|
+
def _fixup_facilities_use(self, kind, child):
|
|
111
|
+
if child.href.get("id") == f"X{kind.label}":
|
|
112
|
+
return 0
|
|
113
|
+
self.msg("fixing facilities (use)")
|
|
114
|
+
child.href = f"X{kind.label}"
|
|
115
|
+
return 1
|
|
116
|
+
|
|
117
|
+
def _fixup_facilities_center(self, kind, child):
|
|
118
|
+
c = None
|
|
119
|
+
if isinstance(child, inkex.Circle):
|
|
120
|
+
c = child.center
|
|
121
|
+
elif isinstance(child, inkex.Ellipse):
|
|
122
|
+
c = child.center
|
|
123
|
+
if c is None:
|
|
124
|
+
return -1
|
|
125
|
+
self.msg("fixing facilities")
|
|
126
|
+
x = inkex.Use()
|
|
127
|
+
x.label = child.label
|
|
128
|
+
x.href = f"X{kind.label}"
|
|
129
|
+
x.transform = f"translate({c.x},{c.y})"
|
|
130
|
+
kind.append(x)
|
|
131
|
+
kind.remove(child)
|
|
132
|
+
return 1
|
|
133
|
+
|
|
134
|
+
def _fixup_facilities(self, node):
|
|
135
|
+
if not isinstance(node, inkex.Group) or node.label != "Facilities":
|
|
136
|
+
return
|
|
137
|
+
for kind in list(node):
|
|
138
|
+
changed = False
|
|
139
|
+
for child in list(kind):
|
|
140
|
+
ok = None
|
|
141
|
+
if isinstance(child, inkex.Use):
|
|
142
|
+
ok = self._fixup_facilities_use(kind, child)
|
|
143
|
+
else:
|
|
144
|
+
ok = self._fixup_facilities_center(kind, child)
|
|
145
|
+
if ok > 0:
|
|
146
|
+
changed = True
|
|
147
|
+
elif ok < 0:
|
|
148
|
+
# XXX
|
|
149
|
+
return
|
|
150
|
+
if changed:
|
|
151
|
+
self._sort_children(kind)
|
|
152
|
+
|
|
153
|
+
def _fixup_marker(self, node):
|
|
154
|
+
if not isinstance(node, inkex.Marker):
|
|
155
|
+
return
|
|
156
|
+
xid = node.get("id")
|
|
157
|
+
if xid == "Triangle":
|
|
158
|
+
return
|
|
159
|
+
self.msg(f"removing marker: {node.label}:{xid}")
|
|
160
|
+
p = node.getparent()
|
|
161
|
+
if p:
|
|
162
|
+
p.remove(node)
|
|
163
|
+
|
|
164
|
+
def _process_addresses(self, node):
|
|
165
|
+
super()._process_addresses(node)
|
|
166
|
+
self.msg("=== fixup start")
|
|
167
|
+
for e in node.descendants():
|
|
168
|
+
self._fixup_facilities(e)
|
|
169
|
+
self._fixup_style(e)
|
|
170
|
+
# XXX group style attribs have purposes & are actually used
|
|
171
|
+
# self._fixup_attrib(e)
|
|
172
|
+
self._fixup_path(e)
|
|
173
|
+
self._fixup_marker(e)
|
|
174
|
+
self.msg("=== fixup done")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == "__main__":
|
|
178
|
+
TidyTree().run()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
3
|
+
<name>Set shop ID</name>
|
|
4
|
+
<id>daijimaps.use_shop</id>
|
|
5
|
+
<label>Set use's href to shop's IDs.</label>
|
|
6
|
+
<param name="tab" type="notebook">
|
|
7
|
+
<page name="Options" gui-text="Options">
|
|
8
|
+
<param name="href" type="string" gui-text="Shop symbol ID:">XShop1</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="Use" />
|
|
16
|
+
</submenu>
|
|
17
|
+
</effects-menu>
|
|
18
|
+
</effect>
|
|
19
|
+
<script>
|
|
20
|
+
<command location="inx" interpreter="python">use_shop.py</command>
|
|
21
|
+
</script>
|
|
22
|
+
</inkscape-extension>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
|
|
4
|
+
from argparse import ArgumentParser
|
|
5
|
+
import inkex
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UseShop(inkex.EffectExtension):
|
|
9
|
+
def _change_use_href(self, node, id_string):
|
|
10
|
+
if not isinstance(node, inkex.Use):
|
|
11
|
+
return
|
|
12
|
+
node.href = id_string
|
|
13
|
+
|
|
14
|
+
def add_arguments(self, pars: ArgumentParser) -> None:
|
|
15
|
+
pars.add_argument("--tab", type=str, dest="tab")
|
|
16
|
+
pars.add_argument("--href", type=str, default="XShop1")
|
|
17
|
+
return super().add_arguments(pars)
|
|
18
|
+
|
|
19
|
+
def effect(self):
|
|
20
|
+
if self.svg.selection:
|
|
21
|
+
for node in self.svg.selection.values():
|
|
22
|
+
self._change_use_href(node, self.options.href)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
UseShop().run()
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Inkscape extensions for DaijiMaps
|
|
2
|
+
|
|
3
|
+
- renumber_group
|
|
4
|
+
- TODO renumber_tree
|
|
5
|
+
- TODO assign_addresses
|
|
6
|
+
- TODO unlabel_group, unlabel_tree
|
|
7
|
+
|
|
8
|
+
- TODO validation
|
|
9
|
+
- TODO fixup
|
|
10
|
+
- TODO classification
|
|
11
|
+
- define classes (e.g. shops, facilities, shop, address, scale, symbol, ...)
|
|
12
|
+
- use Classes (e.g. `node.classes.append('shop')`)
|
|
13
|
+
|
|
14
|
+
## renumber_tree
|
|
15
|
+
|
|
16
|
+
- Skip pattern (`/^[A-Z].*$/`)
|
|
17
|
+
- Terminal condition (`node.get('transform')`)
|
|
18
|
+
|
|
19
|
+
## assign_addresses
|
|
20
|
+
|
|
21
|
+
- e.g. `F1F-Shops-N-1-1`
|
|
22
|
+
- delimiter (`-`)
|
|
23
|
+
- Omit pattern (e.g. `Floor`)
|
|
24
|
+
- 1F/Floor/Shops/... => `1F-Shops-...`
|
|
25
|
+
- Skip pattern (e.g. `Background`)
|
|
26
|
+
- 1F/Background is skipped/ignored
|
|
27
|
+
- prefix, suffix
|
|
28
|
+
|
|
29
|
+
## symbol_load
|
|
30
|
+
|
|
31
|
+
- <g label="Toilets_Inv">
|
|
32
|
+
- <use href="#Toilets_Inv">
|
|
33
|
+
- <g>
|
|
34
|
+
- ...
|