Optimize frequently called functions

Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
Konstantin Pastbin 2023-01-25 18:56:56 +00:00 committed by Viktor Govako
parent 41498a6ec5
commit 70fa78f39b
3 changed files with 53 additions and 96 deletions

View file

@ -33,42 +33,44 @@ class Condition:
def test(self, tags):
"""
Test a hash against this condition
Test tags against this condition
"""
t = self.type
params = self.params
if t == 'eq': # don't compare tags against sublayers
if t == 'eq':
# Don't compare tags against sublayers
if params[0][:2] == "::":
return params[1]
try:
if t == 'eq':
return tags[params[0]] == params[1]
if t == 'ne':
return tags.get(params[0], "") != params[1]
if t == 'regex':
return bool(self.regex.match(tags[params[0]]))
if t == 'true':
return tags.get(params[0]) == 'yes'
if t == 'untrue':
return tags.get(params[0]) == 'no'
if t == 'set':
if params[0] in tags:
return tags[params[0]] != ''
return False
if t == 'unset':
if params[0] in tags:
return tags[params[0]] == ''
return True
if t == '<':
return (Number(tags[params[0]]) < Number(params[1]))
if t == '<=':
return (Number(tags[params[0]]) <= Number(params[1]))
if t == '>':
return (Number(tags[params[0]]) > Number(params[1]))
if t == '>=':
return (Number(tags[params[0]]) >= Number(params[1]))
except KeyError:
pass
return (params[0] in tags and tags[params[0]] == params[1])
if t == 'ne':
return (params[0] not in tags or tags[params[0]] != params[1])
if t == 'true':
return tags.get(params[0]) == 'yes'
if t == 'untrue':
return tags.get(params[0]) == 'no'
if t == 'set':
if params[0] in tags:
return tags[params[0]] != ''
return False
if t == 'unset':
if params[0] in tags:
return tags[params[0]] == ''
return True
if params[0] not in tags:
return False
if t == 'regex':
return bool(self.regex.match(tags[params[0]]))
if t == '<':
return (Number(tags[params[0]]) < Number(params[1]))
if t == '<=':
return (Number(tags[params[0]]) <= Number(params[1]))
if t == '>':
return (Number(tags[params[0]]) > Number(params[1]))
if t == '>=':
return (Number(tags[params[0]]) >= Number(params[1]))
return False
def __repr__(self):

View file

@ -25,7 +25,7 @@ type_matches = {
class Rule():
def __init__(self, s=''):
self.runtime_conditions = []
self.runtime_conditions = None
self.conditions = []
# self.isAnd = True
self.minZoom = 0
@ -33,6 +33,7 @@ class Rule():
if s == "*":
s = ""
self.subject = s # "", "way", "node" or "relation"
self.type_matches = type_matches[s] if s in type_matches else set()
def __repr__(self):
return "%s|z%s-%s %s %s" % (self.subject, self.minZoom, self.maxZoom, self.conditions, self.runtime_conditions)
@ -41,7 +42,7 @@ class Rule():
if (zoom < self.minZoom) or (zoom > self.maxZoom):
return False
if (self.subject != '') and not _test_feature_compatibility(obj, self.subject, tags):
if (obj not in self.type_matches):
return False
subpart = "::default"
@ -66,28 +67,3 @@ class Rule():
return set(["*"])
return a
def _test_feature_compatibility(f1, f2, tags={}):
"""
Checks if feature of type f1 is compatible with f2.
"""
if f2 == f1:
return True
if f2 not in ("way", "area", "line"):
return False
elif f2 == "way" and f1 == "line":
return True
elif f2 == "way" and f1 == "area":
return True
elif f2 == "area" and f1 in ("way", "area"):
# if ":area" in tags:
return True
# else:
# return False
elif f2 == "line" and f1 in ("way", "line", "area"):
return True
else:
return False
# print f1, f2, True
return True

View file

@ -87,6 +87,7 @@ class StyleChooser:
self.selzooms = None
self.compatible_types = set()
self.has_evals = False
self.has_runtime_conditions = False
self.cached_tags = None
def extract_tags(self):
@ -96,32 +97,24 @@ class StyleChooser:
for r in self.ruleChains:
a.update(r.extract_tags())
if "*" in a:
a.clear()
a.add("*")
a = set('*')
break
if self.has_evals and "*" not in a:
for s in self.styles:
for v in list(s.values()):
if type(v) == self.eval_type:
a.update(v.extract_tags())
if "*" in a or len(a) == 0:
a.clear()
a.add("*")
if len(a) == 0:
a = set('*')
self.cached_tags = a
return a
def get_runtime_conditions(self, ftype, tags, zoom):
has_rt_conds = False
for rule in self.ruleChains:
if (len(rule.runtime_conditions) > 0):
has_rt_conds = True
break
if not has_rt_conds:
if not self.has_runtime_conditions:
return None
if self.selzooms:
if zoom < self.selzooms[0] or zoom > self.selzooms[1]:
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)
@ -130,30 +123,11 @@ class StyleChooser:
rule = rule_and_object_id[0]
if (len(rule.runtime_conditions) == 0):
return None
return rule.runtime_conditions
def isCorrespondingRule(self, filter_by_runtime_conditions, rule):
# If rule can be applied according to runtime conditions, then
# function return true, else it returns false
if len(rule.runtime_conditions) == 0:
return True
if filter_by_runtime_conditions is None:
return True
if filter_by_runtime_conditions == rule.runtime_conditions:
return True
# Actually we should check rule.runtime_conditions is a subset of filter_by_runtime_conditions
for r in rule.runtime_conditions:
if r not in filter_by_runtime_conditions:
return False
return True
def updateStyles(self, sl, ftype, tags, zoom, xscale, zscale, filter_by_runtime_conditions):
if self.selzooms:
if zoom < self.selzooms[0] or zoom > self.selzooms[1]:
return sl
if zoom < self.selzooms[0] or zoom > self.selzooms[1]:
return sl
#if ftype not in self.compatible_types:
#return sl
@ -167,7 +141,9 @@ class StyleChooser:
rule = rule_and_object_id[0]
object_id = rule_and_object_id[1]
if not self.isCorrespondingRule(filter_by_runtime_conditions, rule):
if (filter_by_runtime_conditions is not None
and rule.runtime_conditions is not None
and filter_by_runtime_conditions != rule.runtime_conditions):
return sl
for r in self.styles:
@ -257,8 +233,11 @@ class StyleChooser:
"""
adds into the current ruleChain (existing Rule)
"""
self.ruleChains[-1].runtime_conditions.append(c)
self.ruleChains[-1].runtime_conditions.sort()
if self.ruleChains[-1].runtime_conditions is None:
self.ruleChains[-1].runtime_conditions = [c]
self.has_runtime_conditions = True
else:
self.ruleChains[-1].runtime_conditions.append(c)
def addStyles(self, a):
# print "addStyle ", a