From 9b38690e69a9f195688121feebff1078dfa83ae4 Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Tue, 31 Jan 2023 18:07:26 +0000 Subject: [PATCH] Optimize choosers by discarding non-matching rules Signed-off-by: Konstantin Pastbin --- src/mapcss/Rule.py | 8 +------- src/mapcss/StyleChooser.py | 17 +++++++---------- src/mapcss/__init__.py | 21 ++++++++++++++++++--- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/mapcss/Rule.py b/src/mapcss/Rule.py index 0966310..db516c1 100644 --- a/src/mapcss/Rule.py +++ b/src/mapcss/Rule.py @@ -38,13 +38,7 @@ class Rule(): def __repr__(self): return "%s|z%s-%s %s %s" % (self.subject, self.minZoom, self.maxZoom, self.conditions, self.runtime_conditions) - def test(self, obj, tags, zoom): - if (zoom < self.minZoom) or (zoom > self.maxZoom): - return False - - if (obj not in self.type_matches): - return False - + def test(self, tags): subpart = "::default" for condition in self.conditions: res = condition.test(tags) diff --git a/src/mapcss/StyleChooser.py b/src/mapcss/StyleChooser.py index b27b550..a386599 100644 --- a/src/mapcss/StyleChooser.py +++ b/src/mapcss/StyleChooser.py @@ -109,14 +109,11 @@ class StyleChooser: self.cached_tags = a return a - def get_runtime_conditions(self, ftype, tags, zoom): + def get_runtime_conditions(self, tags): if not self.has_runtime_conditions: return None - if zoom < self.selzooms[0] or zoom > self.selzooms[1]: - return None - - rule_and_object_id = self.testChain(self.ruleChains, ftype, tags, zoom) + rule_and_object_id = self.testChains(tags) if not rule_and_object_id: return None @@ -125,9 +122,9 @@ class StyleChooser: return rule.runtime_conditions - def updateStyles(self, sl, ftype, tags, zoom, xscale, zscale, filter_by_runtime_conditions): + def updateStyles(self, sl, tags, xscale, zscale, filter_by_runtime_conditions): # Are any of the ruleChains fulfilled? - rule_and_object_id = self.testChain(self.ruleChains, ftype, tags, zoom) + rule_and_object_id = self.testChains(tags) if not rule_and_object_id: return sl @@ -181,12 +178,12 @@ class StyleChooser: return sl - def testChain(self, chain, obj, tags, zoom): + def testChains(self, tags): """ Tests an object against a chain """ - for r in chain: - tt = r.test(obj, tags, zoom) + for r in self.ruleChains: + tt = r.test(tags) if tt: return r, tt return False diff --git a/src/mapcss/__init__.py b/src/mapcss/__init__.py index feff12a..d52e8a5 100644 --- a/src/mapcss/__init__.py +++ b/src/mapcss/__init__.py @@ -130,11 +130,26 @@ class MapCSS(): self.choosers_by_type_zoom_tag[type][zoom][clname]['set'].add(chooser) def finalize_choosers_tree(self): - # Remove unneeded unique sets of choosers for ftype in self.choosers_by_type_zoom_tag.keys(): for zoom in self.choosers_by_type_zoom_tag[ftype].keys(): for clname in self.choosers_by_type_zoom_tag[ftype][zoom].keys(): + # Discard unneeded unique set of choosers. self.choosers_by_type_zoom_tag[ftype][zoom][clname] = self.choosers_by_type_zoom_tag[ftype][zoom][clname]['arr'] + for i in range(0, len(self.choosers_by_type_zoom_tag[ftype][zoom][clname])): + chooser = self.choosers_by_type_zoom_tag[ftype][zoom][clname][i] + optimized = StyleChooser(chooser.scalepair) + optimized.styles = chooser.styles + optimized.eval_type = chooser.eval_type + optimized.has_evals = chooser.has_evals + optimized.has_runtime_conditions = chooser.has_runtime_conditions + optimized.selzooms = [zoom, zoom] + optimized.ruleChains = [] + for rule in chooser.ruleChains: + # Discard chooser's rules that don't match type or zoom. + if ftype in rule.type_matches and zoom >= rule.minZoom and zoom <= rule.maxZoom: + optimized.ruleChains.append(rule) + self.choosers_by_type_zoom_tag[ftype][zoom][clname][i] = optimized + def get_runtime_rules(self, clname, type, tags, zoom): """ @@ -143,7 +158,7 @@ class MapCSS(): runtime_rules = [] if type in self.choosers_by_type_zoom_tag: for chooser in self.choosers_by_type_zoom_tag[type][zoom][clname]: - runtime_conditions = chooser.get_runtime_conditions(type, tags, zoom) + runtime_conditions = chooser.get_runtime_conditions(tags) if runtime_conditions: runtime_rules.append(runtime_conditions) return runtime_rules @@ -152,7 +167,7 @@ class MapCSS(): style = [] if type in self.choosers_by_type_zoom_tag: for chooser in self.choosers_by_type_zoom_tag[type][zoom][clname]: - style = chooser.updateStyles(style, type, tags, zoom, xscale, zscale, filter_by_runtime_conditions) + style = chooser.updateStyles(style, tags, xscale, zscale, filter_by_runtime_conditions) style = [x for x in style if x["object-id"] != "::*"] for x in style: for k, v in [('width', 0), ('casing-width', 0)]: