Optimize frequently called functions
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
parent
41498a6ec5
commit
70fa78f39b
3 changed files with 53 additions and 96 deletions
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue