forked from organicmaps/organicmaps-tmp
Kothic: implemented runtime selectors
This commit is contained in:
parent
d028412ec2
commit
b29c52d807
5 changed files with 364 additions and 423 deletions
|
@ -1,5 +1,4 @@
|
|||
from drules_struct_pb2 import *
|
||||
from timer import *
|
||||
from mapcss import MapCSS
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
|
@ -13,24 +12,37 @@ whatever_to_cairo = mapcss.webcolors.webcolors.whatever_to_cairo
|
|||
WIDTH_SCALE = 1.0
|
||||
|
||||
|
||||
def komap_mapswithme(options, style):
|
||||
if options.outfile == "-":
|
||||
print "Please specify base output path."
|
||||
exit()
|
||||
else:
|
||||
ddir = os.path.dirname(options.outfile)
|
||||
def mwm_encode_color(st, prefix='', default='black'):
|
||||
if prefix:
|
||||
prefix += "-"
|
||||
opacity = hex(255 - int(255 * float(st.get(prefix + "opacity", 1))))
|
||||
color = whatever_to_hex(st.get(prefix + 'color', default))
|
||||
color = color[1] + color[1] + color[3] + color[3] + color[5] + color[5]
|
||||
return int(opacity + color, 16)
|
||||
|
||||
types_file = open(os.path.join(ddir, 'types.txt'), "w")
|
||||
drules_bin = open(os.path.join(options.outfile + '.bin'), "wb")
|
||||
drules_txt = open(os.path.join(options.outfile + '.txt'), "wb")
|
||||
def mwm_encode_image(st, prefix='icon', bgprefix='symbol'):
|
||||
if prefix:
|
||||
prefix += "-"
|
||||
if bgprefix:
|
||||
bgprefix += "-"
|
||||
if prefix + "image" not in st:
|
||||
return False
|
||||
# strip last ".svg"
|
||||
handle = st.get(prefix + "image")[:-4]
|
||||
return handle, handle
|
||||
|
||||
def komap_mapswithme(options):
|
||||
|
||||
ddir = os.path.dirname(options.outfile)
|
||||
|
||||
classificator = {}
|
||||
class_order = []
|
||||
class_tree = {}
|
||||
visibility = {}
|
||||
textures = {}
|
||||
|
||||
# Build classificator tree from mapcss-mapping.csv file
|
||||
types_file = open(os.path.join(ddir, 'types.txt'), "w")
|
||||
for row in csv.reader(open(os.path.join(ddir, 'mapcss-mapping.csv')), delimiter=';'):
|
||||
cl = row[0].replace("|", "-")
|
||||
pairs = [i.strip(']').split("=") for i in row[1].split(',')[0].split('[')]
|
||||
kv = {}
|
||||
for i in pairs:
|
||||
|
@ -42,9 +54,9 @@ def komap_mapswithme(options, style):
|
|||
kv[i[0].strip('?')] = "yes"
|
||||
else:
|
||||
kv[i[0]] = i[1]
|
||||
classificator[row[0].replace("|", "-")] = kv
|
||||
classificator[cl] = kv
|
||||
if row[2] != "x":
|
||||
class_order.append(row[0].replace("|", "-"))
|
||||
class_order.append(cl)
|
||||
print >> types_file, row[0]
|
||||
else:
|
||||
# compatibility mode
|
||||
|
@ -52,306 +64,262 @@ def komap_mapswithme(options, style):
|
|||
print >> types_file, row[6]
|
||||
else:
|
||||
print >> types_file, "mapswithme"
|
||||
class_tree[row[0].replace("|", "-")] = row[0]
|
||||
class_tree[cl] = row[0]
|
||||
class_order.sort()
|
||||
types_file.close()
|
||||
|
||||
def mwm_encode_color(st, prefix='', default='black'):
|
||||
if prefix:
|
||||
prefix += "-"
|
||||
opacity = hex(255 - int(255 * float(st.get(prefix + "opacity", 1))))
|
||||
color = whatever_to_hex(st.get(prefix + 'color', default))
|
||||
color = color[1] + color[1] + color[3] + color[3] + color[5] + color[5]
|
||||
return int(opacity + color, 16)
|
||||
# Get all mapcss tags which are used in mapcss-mapping.csv
|
||||
mapcss_mapping_tags = set()
|
||||
for v in classificator.values():
|
||||
for t in v.keys():
|
||||
mapcss_mapping_tags.add(t)
|
||||
|
||||
def mwm_encode_image(st, prefix='icon', bgprefix='symbol'):
|
||||
if prefix:
|
||||
prefix += "-"
|
||||
if bgprefix:
|
||||
bgprefix += "-"
|
||||
if prefix + "image" not in st:
|
||||
return False
|
||||
# strip last ".svg"
|
||||
handle = st.get(prefix + "image")[:-4]
|
||||
return handle, handle
|
||||
# Parse style mapcss
|
||||
style = MapCSS(options.minzoom, options.maxzoom + 1)
|
||||
style.parse(filename = options.filename, mapcss_tags = mapcss_mapping_tags)
|
||||
|
||||
# Build optimization tree - class/type -> StyleChoosers
|
||||
for cl in class_order:
|
||||
clname = cl if cl.find('-') == -1 else cl[:cl.find('-')]
|
||||
cltags = classificator[cl]
|
||||
style.build_choosers_tree(clname, "line", cltags)
|
||||
style.build_choosers_tree(clname, "area", cltags)
|
||||
style.build_choosers_tree(clname, "node", cltags)
|
||||
style.restore_choosers_order("line")
|
||||
style.restore_choosers_order("area")
|
||||
style.restore_choosers_order("node")
|
||||
|
||||
visibility = {}
|
||||
|
||||
bgpos = 0
|
||||
|
||||
dr_linecaps = {'none': BUTTCAP, 'butt': BUTTCAP, 'round': ROUNDCAP}
|
||||
dr_linejoins = {'none': NOJOIN, 'bevel': BEVELJOIN, 'round': ROUNDJOIN}
|
||||
|
||||
# atbuild = AccumulativeTimer()
|
||||
# atzstyles = AccumulativeTimer()
|
||||
# atdrcont = AccumulativeTimer()
|
||||
# atline = AccumulativeTimer()
|
||||
# atarea = AccumulativeTimer()
|
||||
# atnode = AccumulativeTimer()
|
||||
|
||||
# atbuild.Start()
|
||||
|
||||
for cl in class_order:
|
||||
clname = cl if cl.find('-') == -1 else cl[:cl.find('-')]
|
||||
# clname = cl
|
||||
style.build_choosers_tree(clname, "line", classificator[cl])
|
||||
style.build_choosers_tree(clname, "area", classificator[cl])
|
||||
style.build_choosers_tree(clname, "node", classificator[cl])
|
||||
|
||||
style.restore_choosers_order("line")
|
||||
style.restore_choosers_order("area")
|
||||
style.restore_choosers_order("node")
|
||||
|
||||
# atbuild.Stop()
|
||||
# Build drules tree
|
||||
|
||||
drules = ContainerProto()
|
||||
|
||||
for cl in class_order:
|
||||
visstring = ["0"] * (options.maxzoom - options.minzoom + 1)
|
||||
|
||||
clname = cl if cl.find('-') == -1 else cl[:cl.find('-')]
|
||||
# clname = cl
|
||||
txclass = classificator[cl]
|
||||
txclass["name"] = "name"
|
||||
txclass["addr:housenumber"] = "addr:housenumber"
|
||||
txclass["ref"] = "ref"
|
||||
txclass["int_name"] = "int_name"
|
||||
txclass["addr:flats"] = "addr:flats"
|
||||
|
||||
prev_area_len = -1
|
||||
prev_node_len = -1
|
||||
prev_line_len = -1
|
||||
check_area = True
|
||||
check_node = True
|
||||
check_line = True
|
||||
|
||||
# atzstyles.Start()
|
||||
|
||||
zstyles_arr = [None] * (options.maxzoom - options.minzoom + 1)
|
||||
has_icons_for_areas_arr = [False] * (options.maxzoom - options.minzoom + 1)
|
||||
|
||||
for zoom in xrange(options.maxzoom, options.minzoom - 1, -1):
|
||||
has_icons_for_areas = False
|
||||
zstyle = {}
|
||||
|
||||
if check_line:
|
||||
if "area" not in txclass:
|
||||
# atline.Start()
|
||||
linestyle = style.get_style_dict(clname, "line", txclass, zoom, olddict=zstyle)
|
||||
if prev_line_len == -1:
|
||||
prev_line_len = len(linestyle)
|
||||
if len(linestyle) == 0:
|
||||
if prev_line_len != 0:
|
||||
check_line = False
|
||||
zstyle = linestyle
|
||||
# atline.Stop()
|
||||
|
||||
if check_area:
|
||||
# atarea.Start()
|
||||
areastyle = style.get_style_dict(clname, "area", txclass, zoom, olddict=zstyle)
|
||||
for st in areastyle.values():
|
||||
if "icon-image" in st or 'symbol-shape' in st or 'symbol-image' in st:
|
||||
has_icons_for_areas = True
|
||||
break
|
||||
if prev_area_len == -1:
|
||||
prev_area_len = len(areastyle)
|
||||
if len(areastyle) == 0:
|
||||
if prev_area_len != 0:
|
||||
check_area = False
|
||||
zstyle = areastyle
|
||||
# atarea.Stop()
|
||||
|
||||
if check_node:
|
||||
if "area" not in txclass:
|
||||
# atnode.Start()
|
||||
nodestyle = style.get_style_dict(clname, "node", txclass, zoom, olddict=zstyle)
|
||||
if prev_node_len == -1:
|
||||
prev_node_len = len(nodestyle)
|
||||
if len(nodestyle) == 0:
|
||||
if prev_node_len != 0:
|
||||
check_node = False
|
||||
zstyle = nodestyle
|
||||
# atnode.Stop()
|
||||
|
||||
if not check_line and not check_area and not check_node:
|
||||
break
|
||||
|
||||
zstyle = zstyle.values()
|
||||
|
||||
zstyles_arr[zoom - options.minzoom] = zstyle
|
||||
has_icons_for_areas_arr[zoom - options.minzoom]= has_icons_for_areas
|
||||
|
||||
# atzstyles.Stop()
|
||||
|
||||
# atdrcont.Start()
|
||||
cltags = classificator[cl]
|
||||
cltags["name"] = "name"
|
||||
cltags["addr:housenumber"] = "addr:housenumber"
|
||||
cltags["ref"] = "ref"
|
||||
cltags["int_name"] = "int_name"
|
||||
cltags["addr:flats"] = "addr:flats"
|
||||
|
||||
dr_cont = ClassifElementProto()
|
||||
dr_cont.name = cl
|
||||
|
||||
visstring = ["0"] * (options.maxzoom - options.minzoom + 1)
|
||||
|
||||
for zoom in xrange(options.minzoom, options.maxzoom + 1):
|
||||
zstyle = zstyles_arr[zoom - options.minzoom]
|
||||
if zstyle is None or len(zstyle) == 0:
|
||||
continue
|
||||
|
||||
has_icons_for_areas = has_icons_for_areas_arr[zoom - options.minzoom]
|
||||
runtime_conditions_arr = []
|
||||
|
||||
has_lines = False
|
||||
has_icons = False
|
||||
has_fills = False
|
||||
for st in zstyle:
|
||||
st = dict([(k, v) for k, v in st.iteritems() if str(v).strip(" 0.")])
|
||||
if 'width' in st or 'pattern-image' in st:
|
||||
has_lines = True
|
||||
if 'icon-image' in st or 'symbol-shape' in st or 'symbol-image' in st:
|
||||
has_icons = True
|
||||
if 'fill-color' in st:
|
||||
has_fills = True
|
||||
# Get runtime conditions which are used for class 'cl' on zoom 'zoom'
|
||||
if "area" not in cltags:
|
||||
runtime_conditions_arr.extend( style.get_runtime_rules(clname, "line", cltags, zoom) )
|
||||
runtime_conditions_arr.extend( style.get_runtime_rules(clname, "area", cltags, zoom) )
|
||||
if "area" not in cltags:
|
||||
runtime_conditions_arr.extend( style.get_runtime_rules(clname, "node", cltags, zoom) )
|
||||
|
||||
has_text = None
|
||||
txfmt = []
|
||||
for st in zstyle:
|
||||
if st.get('text') and not st.get('text') in txfmt:
|
||||
txfmt.append(st.get('text'))
|
||||
if has_text is None:
|
||||
has_text = []
|
||||
has_text.append(st)
|
||||
# If there is no any runtime conditions, do not filter style by runtime conditions
|
||||
if len(runtime_conditions_arr) == 0:
|
||||
runtime_conditions_arr.append(None)
|
||||
|
||||
if (not has_lines) and (not has_text) and (not has_fills) and (not has_icons):
|
||||
continue
|
||||
for runtime_conditions in runtime_conditions_arr:
|
||||
|
||||
visstring[zoom] = "1"
|
||||
dr_element = DrawElementProto()
|
||||
dr_element.scale = zoom
|
||||
has_icons_for_areas = False
|
||||
zstyle = {}
|
||||
|
||||
for st in zstyle:
|
||||
if st.get('-x-kot-layer') == 'top':
|
||||
st['z-index'] = float(st.get('z-index', 0)) + 15001.
|
||||
elif st.get('-x-kot-layer') == 'bottom':
|
||||
st['z-index'] = float(st.get('z-index', 0)) - 15001.
|
||||
# Get style for class 'cl' on zoom 'zoom' with corresponding runtime conditions
|
||||
if "area" not in cltags:
|
||||
linestyle = style.get_style_dict(clname, "line", cltags, zoom, olddict=zstyle, filter_by_runtime_conditions=runtime_conditions)
|
||||
zstyle = linestyle
|
||||
areastyle = style.get_style_dict(clname, "area", cltags, zoom, olddict=zstyle, filter_by_runtime_conditions=runtime_conditions)
|
||||
for st in areastyle.values():
|
||||
if "icon-image" in st or 'symbol-shape' in st or 'symbol-image' in st:
|
||||
has_icons_for_areas = True
|
||||
break
|
||||
zstyle = areastyle
|
||||
if "area" not in cltags:
|
||||
nodestyle = style.get_style_dict(clname, "node", cltags, zoom, olddict=zstyle, filter_by_runtime_conditions=runtime_conditions)
|
||||
zstyle = nodestyle
|
||||
|
||||
if st.get('casing-width') not in (None, 0): # and (st.get('width') or st.get('fill-color')):
|
||||
if st.get('casing-linecap', 'butt') == 'butt':
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = (st.get('width', 0) * WIDTH_SCALE) + (st.get('casing-width') * WIDTH_SCALE * 2)
|
||||
dr_line.color = mwm_encode_color(st, "casing")
|
||||
dr_line.priority = min(int(st.get('z-index', 0) + 999), 20000)
|
||||
dashes = st.get('casing-dashes', st.get('dashes', []))
|
||||
dr_line.dashdot.dd.extend(dashes)
|
||||
dr_line.cap = dr_linecaps.get(st.get('casing-linecap', 'butt'), BUTTCAP)
|
||||
dr_line.join = dr_linejoins.get(st.get('casing-linejoin', 'round'), ROUNDJOIN)
|
||||
dr_element.lines.extend([dr_line])
|
||||
zstyle = zstyle.values()
|
||||
|
||||
# Let's try without this additional line style overhead. Needed only for casing in road endings.
|
||||
# if st.get('casing-linecap', st.get('linecap', 'round')) != 'butt':
|
||||
# dr_line = LineRuleProto()
|
||||
# dr_line.width = (st.get('width', 0) * WIDTH_SCALE) + (st.get('casing-width') * WIDTH_SCALE * 2)
|
||||
# dr_line.color = mwm_encode_color(st, "casing")
|
||||
# dr_line.priority = -15000
|
||||
# dashes = st.get('casing-dashes', st.get('dashes', []))
|
||||
# dr_line.dashdot.dd.extend(dashes)
|
||||
# dr_line.cap = dr_linecaps.get(st.get('casing-linecap', 'round'), ROUNDCAP)
|
||||
# dr_line.join = dr_linejoins.get(st.get('casing-linejoin', 'round'), ROUNDJOIN)
|
||||
# dr_element.lines.extend([dr_line])
|
||||
if len(zstyle) == 0:
|
||||
continue
|
||||
|
||||
if has_lines:
|
||||
if st.get('width'):
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = (st.get('width', 0) * WIDTH_SCALE)
|
||||
dr_line.color = mwm_encode_color(st)
|
||||
for i in st.get('dashes', []):
|
||||
dr_line.dashdot.dd.extend([max(float(i), 1) * WIDTH_SCALE])
|
||||
dr_line.cap = dr_linecaps.get(st.get('linecap', 'butt'), BUTTCAP)
|
||||
dr_line.join = dr_linejoins.get(st.get('linejoin', 'round'), ROUNDJOIN)
|
||||
dr_line.priority = min((int(st.get('z-index', 0)) + 1000), 20000)
|
||||
dr_element.lines.extend([dr_line])
|
||||
if st.get('pattern-image'):
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = 0
|
||||
dr_line.color = 0
|
||||
icon = mwm_encode_image(st, prefix='pattern')
|
||||
dr_line.pathsym.name = icon[0]
|
||||
dr_line.pathsym.step = float(st.get('pattern-spacing', 0)) - 16
|
||||
dr_line.pathsym.offset = st.get('pattern-offset', 0)
|
||||
dr_line.priority = int(st.get('z-index', 0)) + 1000
|
||||
dr_element.lines.extend([dr_line])
|
||||
textures[icon[0]] = icon[1]
|
||||
if st.get('shield-font-size'):
|
||||
dr_element.shield.height = int(st.get('shield-font-size', 10))
|
||||
dr_element.shield.color = mwm_encode_color(st, "shield-text")
|
||||
if st.get('shield-text-halo-radius', 0) != 0:
|
||||
dr_element.shield.stroke_color = mwm_encode_color(st, "shield-text-halo", "white")
|
||||
dr_element.shield.priority = min(19100, (16000 + int(st.get('z-index', 0))))
|
||||
has_lines = False
|
||||
has_icons = False
|
||||
has_fills = False
|
||||
for st in zstyle:
|
||||
st = dict([(k, v) for k, v in st.iteritems() if str(v).strip(" 0.")])
|
||||
if 'width' in st or 'pattern-image' in st:
|
||||
has_lines = True
|
||||
if 'icon-image' in st or 'symbol-shape' in st or 'symbol-image' in st:
|
||||
has_icons = True
|
||||
if 'fill-color' in st:
|
||||
has_fills = True
|
||||
|
||||
if has_icons:
|
||||
if st.get('icon-image'):
|
||||
if not has_icons_for_areas:
|
||||
dr_element.symbol.apply_for_type = 1
|
||||
icon = mwm_encode_image(st)
|
||||
dr_element.symbol.name = icon[0]
|
||||
dr_element.symbol.priority = min(19100, (16000 + int(st.get('z-index', 0))))
|
||||
textures[icon[0]] = icon[1]
|
||||
has_icons = False
|
||||
if st.get('symbol-shape'):
|
||||
dr_element.circle.radius = float(st.get('symbol-size'))
|
||||
dr_element.circle.color = mwm_encode_color(st, 'symbol-fill')
|
||||
dr_element.circle.priority = min(19000, (14000 + int(st.get('z-index', 0))))
|
||||
has_icons = False
|
||||
has_text = None
|
||||
txfmt = []
|
||||
for st in zstyle:
|
||||
if st.get('text') and not st.get('text') in txfmt:
|
||||
txfmt.append(st.get('text'))
|
||||
if has_text is None:
|
||||
has_text = []
|
||||
has_text.append(st)
|
||||
|
||||
if has_text and st.get('text'):
|
||||
has_text = has_text[:2]
|
||||
has_text.reverse()
|
||||
dr_text = dr_element.path_text
|
||||
base_z = 15000
|
||||
if st.get('text-position', 'center') == 'line':
|
||||
if (not has_lines) and (not has_text) and (not has_fills) and (not has_icons):
|
||||
continue
|
||||
|
||||
visstring[zoom] = "1"
|
||||
|
||||
dr_element = DrawElementProto()
|
||||
dr_element.scale = zoom
|
||||
|
||||
if runtime_conditions:
|
||||
for rc in runtime_conditions:
|
||||
dr_element.apply_if.append(str(rc))
|
||||
|
||||
for st in zstyle:
|
||||
if st.get('-x-kot-layer') == 'top':
|
||||
st['z-index'] = float(st.get('z-index', 0)) + 15001.
|
||||
elif st.get('-x-kot-layer') == 'bottom':
|
||||
st['z-index'] = float(st.get('z-index', 0)) - 15001.
|
||||
|
||||
if st.get('casing-width') not in (None, 0): # and (st.get('width') or st.get('fill-color')):
|
||||
if st.get('casing-linecap', 'butt') == 'butt':
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = (st.get('width', 0) * WIDTH_SCALE) + (st.get('casing-width') * WIDTH_SCALE * 2)
|
||||
dr_line.color = mwm_encode_color(st, "casing")
|
||||
dr_line.priority = min(int(st.get('z-index', 0) + 999), 20000)
|
||||
dashes = st.get('casing-dashes', st.get('dashes', []))
|
||||
dr_line.dashdot.dd.extend(dashes)
|
||||
dr_line.cap = dr_linecaps.get(st.get('casing-linecap', 'butt'), BUTTCAP)
|
||||
dr_line.join = dr_linejoins.get(st.get('casing-linejoin', 'round'), ROUNDJOIN)
|
||||
dr_element.lines.extend([dr_line])
|
||||
|
||||
# Let's try without this additional line style overhead. Needed only for casing in road endings.
|
||||
# if st.get('casing-linecap', st.get('linecap', 'round')) != 'butt':
|
||||
# dr_line = LineRuleProto()
|
||||
# dr_line.width = (st.get('width', 0) * WIDTH_SCALE) + (st.get('casing-width') * WIDTH_SCALE * 2)
|
||||
# dr_line.color = mwm_encode_color(st, "casing")
|
||||
# dr_line.priority = -15000
|
||||
# dashes = st.get('casing-dashes', st.get('dashes', []))
|
||||
# dr_line.dashdot.dd.extend(dashes)
|
||||
# dr_line.cap = dr_linecaps.get(st.get('casing-linecap', 'round'), ROUNDCAP)
|
||||
# dr_line.join = dr_linejoins.get(st.get('casing-linejoin', 'round'), ROUNDJOIN)
|
||||
# dr_element.lines.extend([dr_line])
|
||||
|
||||
if has_lines:
|
||||
if st.get('width'):
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = (st.get('width', 0) * WIDTH_SCALE)
|
||||
dr_line.color = mwm_encode_color(st)
|
||||
for i in st.get('dashes', []):
|
||||
dr_line.dashdot.dd.extend([max(float(i), 1) * WIDTH_SCALE])
|
||||
dr_line.cap = dr_linecaps.get(st.get('linecap', 'butt'), BUTTCAP)
|
||||
dr_line.join = dr_linejoins.get(st.get('linejoin', 'round'), ROUNDJOIN)
|
||||
dr_line.priority = min((int(st.get('z-index', 0)) + 1000), 20000)
|
||||
dr_element.lines.extend([dr_line])
|
||||
if st.get('pattern-image'):
|
||||
dr_line = LineRuleProto()
|
||||
dr_line.width = 0
|
||||
dr_line.color = 0
|
||||
icon = mwm_encode_image(st, prefix='pattern')
|
||||
dr_line.pathsym.name = icon[0]
|
||||
dr_line.pathsym.step = float(st.get('pattern-spacing', 0)) - 16
|
||||
dr_line.pathsym.offset = st.get('pattern-offset', 0)
|
||||
dr_line.priority = int(st.get('z-index', 0)) + 1000
|
||||
dr_element.lines.extend([dr_line])
|
||||
if st.get('shield-font-size'):
|
||||
dr_element.shield.height = int(st.get('shield-font-size', 10))
|
||||
dr_element.shield.color = mwm_encode_color(st, "shield-text")
|
||||
if st.get('shield-text-halo-radius', 0) != 0:
|
||||
dr_element.shield.stroke_color = mwm_encode_color(st, "shield-text-halo", "white")
|
||||
dr_element.shield.priority = min(19100, (16000 + int(st.get('z-index', 0))))
|
||||
|
||||
if has_icons:
|
||||
if st.get('icon-image'):
|
||||
if not has_icons_for_areas:
|
||||
dr_element.symbol.apply_for_type = 1
|
||||
icon = mwm_encode_image(st)
|
||||
dr_element.symbol.name = icon[0]
|
||||
dr_element.symbol.priority = min(19100, (16000 + int(st.get('z-index', 0))))
|
||||
has_icons = False
|
||||
if st.get('symbol-shape'):
|
||||
dr_element.circle.radius = float(st.get('symbol-size'))
|
||||
dr_element.circle.color = mwm_encode_color(st, 'symbol-fill')
|
||||
dr_element.circle.priority = min(19000, (14000 + int(st.get('z-index', 0))))
|
||||
has_icons = False
|
||||
|
||||
if has_text and st.get('text'):
|
||||
has_text = has_text[:2]
|
||||
has_text.reverse()
|
||||
dr_text = dr_element.path_text
|
||||
base_z = 16000
|
||||
else:
|
||||
dr_text = dr_element.caption
|
||||
for sp in has_text[:]:
|
||||
dr_cur_subtext = dr_text.primary
|
||||
if len(has_text) == 2:
|
||||
dr_cur_subtext = dr_text.secondary
|
||||
dr_cur_subtext.height = int(float(sp.get('font-size', "10").split(",")[0]))
|
||||
dr_cur_subtext.color = mwm_encode_color(sp, "text")
|
||||
if st.get('text-halo-radius', 0) != 0:
|
||||
dr_cur_subtext.stroke_color = mwm_encode_color(sp, "text-halo", "white")
|
||||
if 'text-offset' in sp or 'text-offset-y' in sp:
|
||||
dr_cur_subtext.offset_y = int(sp.get('text-offset-y', sp.get('text-offset', 0)))
|
||||
if 'text-offset-x' in sp:
|
||||
dr_cur_subtext.offset_x = int(sp.get('text-offset-x', 0))
|
||||
has_text.pop()
|
||||
dr_text.priority = min(19000, (base_z + int(st.get('z-index', 0))))
|
||||
has_text = None
|
||||
|
||||
if has_fills:
|
||||
if ('fill-color' in st) and (float(st.get('fill-opacity', 1)) > 0):
|
||||
dr_element.area.color = mwm_encode_color(st, "fill")
|
||||
if st.get('fill-position', 'foreground') == 'background':
|
||||
if 'z-index' not in st:
|
||||
bgpos -= 1
|
||||
dr_element.area.priority = bgpos - 16000
|
||||
else:
|
||||
zzz = int(st.get('z-index', 0))
|
||||
if zzz > 0:
|
||||
dr_element.area.priority = zzz - 16000
|
||||
else:
|
||||
dr_element.area.priority = zzz - 16700
|
||||
base_z = 15000
|
||||
if st.get('text-position', 'center') == 'line':
|
||||
dr_text = dr_element.path_text
|
||||
base_z = 16000
|
||||
else:
|
||||
dr_element.area.priority = (int(st.get('z-index', 0)) + 1 + 1000)
|
||||
has_fills = False
|
||||
dr_text = dr_element.caption
|
||||
for sp in has_text[:]:
|
||||
dr_cur_subtext = dr_text.primary
|
||||
if len(has_text) == 2:
|
||||
dr_cur_subtext = dr_text.secondary
|
||||
dr_cur_subtext.height = int(float(sp.get('font-size', "10").split(",")[0]))
|
||||
dr_cur_subtext.color = mwm_encode_color(sp, "text")
|
||||
if st.get('text-halo-radius', 0) != 0:
|
||||
dr_cur_subtext.stroke_color = mwm_encode_color(sp, "text-halo", "white")
|
||||
if 'text-offset' in sp or 'text-offset-y' in sp:
|
||||
dr_cur_subtext.offset_y = int(sp.get('text-offset-y', sp.get('text-offset', 0)))
|
||||
if 'text-offset-x' in sp:
|
||||
dr_cur_subtext.offset_x = int(sp.get('text-offset-x', 0))
|
||||
has_text.pop()
|
||||
dr_text.priority = min(19000, (base_z + int(st.get('z-index', 0))))
|
||||
has_text = None
|
||||
|
||||
dr_cont.element.extend([dr_element])
|
||||
if has_fills:
|
||||
if ('fill-color' in st) and (float(st.get('fill-opacity', 1)) > 0):
|
||||
dr_element.area.color = mwm_encode_color(st, "fill")
|
||||
if st.get('fill-position', 'foreground') == 'background':
|
||||
if 'z-index' not in st:
|
||||
bgpos -= 1
|
||||
dr_element.area.priority = bgpos - 16000
|
||||
else:
|
||||
zzz = int(st.get('z-index', 0))
|
||||
if zzz > 0:
|
||||
dr_element.area.priority = zzz - 16000
|
||||
else:
|
||||
dr_element.area.priority = zzz - 16700
|
||||
else:
|
||||
dr_element.area.priority = (int(st.get('z-index', 0)) + 1 + 1000)
|
||||
has_fills = False
|
||||
|
||||
dr_cont.element.extend([dr_element])
|
||||
|
||||
if dr_cont.element:
|
||||
drules.cont.extend([dr_cont])
|
||||
|
||||
# atdrcont.Stop()
|
||||
|
||||
visibility["world|" + class_tree[cl] + "|"] = "".join(visstring)
|
||||
|
||||
# atwrite = AccumulativeTimer()
|
||||
# atwrite.Start()
|
||||
# Write drules_proto.bin and drules_proto.txt files
|
||||
|
||||
drules_bin = open(os.path.join(options.outfile + '.bin'), "wb")
|
||||
drules_txt = open(os.path.join(options.outfile + '.txt'), "wb")
|
||||
drules_bin.write(drules.SerializeToString())
|
||||
drules_txt.write(unicode(drules))
|
||||
drules_bin.close()
|
||||
drules_txt.close()
|
||||
|
||||
# Write classificator.txt and visibility.txt files
|
||||
|
||||
visnodes = set()
|
||||
for k, v in visibility.iteritems():
|
||||
|
@ -379,7 +347,6 @@ def komap_mapswithme(options, style):
|
|||
for i in range(len(oldoffset) / 4, len(offset) / 4, -1):
|
||||
print >> visibility_file, " " * i + "{}"
|
||||
print >> classificator_file, " " * i + "{}"
|
||||
|
||||
oldoffset = offset
|
||||
end = "-"
|
||||
if k in visnodes:
|
||||
|
@ -390,48 +357,31 @@ def komap_mapswithme(options, style):
|
|||
print >> visibility_file, " " * i + "{}"
|
||||
print >> classificator_file, " " * i + "{}"
|
||||
|
||||
# atwrite.Stop()
|
||||
|
||||
# print "build, sec: %s" % (atbuild.ElapsedSec())
|
||||
# print "zstyle %s times, sec: %s" % (atzstyles.Count(), atzstyles.ElapsedSec())
|
||||
# print "drcont %s times, sec: %s" % (atdrcont.Count(), atdrcont.ElapsedSec())
|
||||
# print "line %s times, sec: %s" % (atline.Count(), atline.ElapsedSec())
|
||||
# print "area %s times, sec: %s" % (atarea.Count(), atarea.ElapsedSec())
|
||||
# print "node %s times, sec: %s" % (atnode.Count(), atnode.ElapsedSec())
|
||||
# print "writing files, sec: %s" % (atwrite.ElapsedSec())
|
||||
visibility_file.close()
|
||||
classificator_file.close()
|
||||
|
||||
# Main
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-s", "--stylesheet", dest="filename",
|
||||
help="read MapCSS stylesheet from FILE", metavar="FILE")
|
||||
parser.add_option("-f", "--minzoom", dest="minzoom", default=0, type="int",
|
||||
help="minimal available zoom level", metavar="ZOOM")
|
||||
parser.add_option("-t", "--maxzoom", dest="maxzoom", default=19, type="int",
|
||||
help="maximal available zoom level", metavar="ZOOM")
|
||||
parser.add_option("-o", "--output-file", dest="outfile", default="-",
|
||||
help="output filename (defaults to stdout)", metavar="FILE")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if (options.filename is None):
|
||||
parser.error("MapCSS stylesheet filename is required")
|
||||
|
||||
try:
|
||||
# atparse = AccumulativeTimer()
|
||||
# atbuild = AccumulativeTimer()
|
||||
parser = OptionParser()
|
||||
parser.add_option("-s", "--stylesheet", dest="filename",
|
||||
help="read MapCSS stylesheet from FILE", metavar="FILE")
|
||||
parser.add_option("-f", "--minzoom", dest="minzoom", default=0, type="int",
|
||||
help="minimal available zoom level", metavar="ZOOM")
|
||||
parser.add_option("-t", "--maxzoom", dest="maxzoom", default=19, type="int",
|
||||
help="maximal available zoom level", metavar="ZOOM")
|
||||
parser.add_option("-o", "--output-file", dest="outfile", default="-",
|
||||
help="output filename (defaults to stdout)", metavar="FILE")
|
||||
|
||||
# atparse.Start()
|
||||
style = MapCSS(options.minzoom, options.maxzoom + 1) # zoom levels
|
||||
style.parse(filename = options.filename)
|
||||
# atparse.Stop()
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# atbuild.Start()
|
||||
komap_mapswithme(options, style)
|
||||
# atbuild.Stop()
|
||||
if (options.filename is None):
|
||||
parser.error("MapCSS stylesheet filename is required")
|
||||
|
||||
# print "mapcss parse, sec: %s" % (atparse.ElapsedSec())
|
||||
# print "build, sec: %s" % (atbuild.ElapsedSec())
|
||||
if options.outfile == "-":
|
||||
parser.error("Please specify base output path.")
|
||||
|
||||
komap_mapswithme(options)
|
||||
|
||||
exit(0)
|
||||
|
||||
|
|
|
@ -17,95 +17,19 @@
|
|||
|
||||
import re
|
||||
|
||||
# Fast conditions
|
||||
|
||||
class EqConditionDD:
|
||||
def __init__(self, params):
|
||||
self.value = params[1]
|
||||
def extract_tags(self):
|
||||
return set(["*"])
|
||||
def test(self, tags):
|
||||
return self.value
|
||||
|
||||
class EqCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
self.value = params[1]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] == self.value
|
||||
else:
|
||||
return False
|
||||
|
||||
class NotEqCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
self.value = params[1]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] != self.value
|
||||
else:
|
||||
return False
|
||||
|
||||
class SetCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] != ''
|
||||
return False
|
||||
|
||||
class UnsetCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] == ''
|
||||
return True
|
||||
|
||||
class TrueCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] == 'yes'
|
||||
return False
|
||||
|
||||
class UntrueCondition:
|
||||
def __init__(self, params):
|
||||
self.tag = params[0]
|
||||
def extract_tags(self):
|
||||
return set([self.tag])
|
||||
def test(self, tags):
|
||||
if self.tag in tags:
|
||||
return tags[self.tag] == 'no'
|
||||
return False
|
||||
|
||||
# Slow condition
|
||||
|
||||
class Condition:
|
||||
def __init__(self, typez, params):
|
||||
self.type = typez # eq, regex, lt, gt etc.
|
||||
if type(params) == type(str()):
|
||||
params = (params,)
|
||||
self.params = params # e.g. ('highway','primary')
|
||||
self.params = params # e.g. ('highway','primary')
|
||||
if typez == "regex":
|
||||
self.regex = re.compile(self.params[0], re.I)
|
||||
|
||||
def extract_tags(self):
|
||||
def extract_tag(self):
|
||||
if self.params[0][:2] == "::" or self.type == "regex":
|
||||
return set(["*"]) # unknown
|
||||
return set([self.params[0]])
|
||||
return "*" # unknown
|
||||
return self.params[0]
|
||||
|
||||
def test(self, tags):
|
||||
"""
|
||||
|
@ -148,6 +72,32 @@ class Condition:
|
|||
return False
|
||||
|
||||
def __repr__(self):
|
||||
t = self.type
|
||||
params = self.params
|
||||
if t == 'eq' and params[0][:2] == "::":
|
||||
return "::%s" % (params[1])
|
||||
if t == 'eq':
|
||||
return "%s=%s" % (params[0], params[1])
|
||||
if t == 'ne':
|
||||
return "%s=%s" % (params[0], params[1])
|
||||
if t == 'regex':
|
||||
return "%s=~/%s/" % (params[0], params[1]);
|
||||
if t == 'true':
|
||||
return "%s?" % (params[0])
|
||||
if t == 'untrue':
|
||||
return "!%s?" % (params[0])
|
||||
if t == 'set':
|
||||
return "%s" % (params[0])
|
||||
if t == 'unset':
|
||||
return "!%s" % (params[0])
|
||||
if t == '<':
|
||||
return "%s<%s" % (params[0], params[1])
|
||||
if t == '<=':
|
||||
return "%s<=%s" % (params[0], params[1])
|
||||
if t == '>':
|
||||
return "%s>%s" % (params[0], params[1])
|
||||
if t == '>=':
|
||||
return "%s>=%s" % (params[0], params[1])
|
||||
return "%s %s " % (self.type, repr(self.params))
|
||||
|
||||
def __eq__(self, a):
|
||||
|
@ -162,23 +112,3 @@ def Number(tt):
|
|||
except ValueError:
|
||||
return 0
|
||||
|
||||
# Some conditions we can optimize by using "python polymorthism"
|
||||
|
||||
def OptimizeCondition(condition):
|
||||
if (condition.type == "eq"):
|
||||
if (condition.params[0][:2] == "::"):
|
||||
return EqConditionDD(condition.params)
|
||||
else:
|
||||
return EqCondition(condition.params)
|
||||
elif (condition.type == "ne"):
|
||||
return NotEqCondition(condition.params)
|
||||
elif (condition.type == "set"):
|
||||
return SetCondition(condition.params)
|
||||
elif (condition.type == "unset"):
|
||||
return UnsetCondition(condition.params)
|
||||
elif (condition.type == "true"):
|
||||
return TrueCondition(condition.params)
|
||||
elif (condition.type == "untrue"):
|
||||
return UntrueCondition(condition.params)
|
||||
else:
|
||||
return condition
|
||||
|
|
|
@ -25,6 +25,7 @@ type_matches = {
|
|||
|
||||
class Rule():
|
||||
def __init__(self, s=''):
|
||||
self.runtime_conditions = []
|
||||
self.conditions = []
|
||||
# self.isAnd = True
|
||||
self.minZoom = 0
|
||||
|
@ -34,7 +35,7 @@ class Rule():
|
|||
self.subject = s # "", "way", "node" or "relation"
|
||||
|
||||
def __repr__(self):
|
||||
return "%s|z%s-%s %s" % (self.subject, self.minZoom, self.maxZoom, self.conditions)
|
||||
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):
|
||||
|
@ -58,8 +59,9 @@ class Rule():
|
|||
def extract_tags(self):
|
||||
a = set()
|
||||
for condition in self.conditions:
|
||||
a.update(condition.extract_tags())
|
||||
a.add(condition.extract_tag())
|
||||
if "*" in a:
|
||||
a = set(["*"])
|
||||
break
|
||||
return a
|
||||
|
||||
|
|
|
@ -106,7 +106,24 @@ class StyleChooser:
|
|||
a.add("*")
|
||||
return a
|
||||
|
||||
def updateStyles(self, sl, ftype, tags, zoom, scale, zscale):
|
||||
def get_runtime_conditions(self, ftype, tags, zoom):
|
||||
if self.selzooms:
|
||||
if zoom < self.selzooms[0] or zoom > self.selzooms[1]:
|
||||
return None
|
||||
|
||||
rule_and_object_id = self.testChain(self.ruleChains, ftype, tags, zoom)
|
||||
|
||||
if not rule_and_object_id:
|
||||
return None
|
||||
|
||||
rule = rule_and_object_id[0]
|
||||
|
||||
if (len(rule.runtime_conditions) == 0):
|
||||
return None
|
||||
|
||||
return rule.runtime_conditions
|
||||
|
||||
def updateStyles(self, sl, ftype, tags, zoom, xscale, zscale, filter_by_runtime_conditions):
|
||||
# Are any of the ruleChains fulfilled?
|
||||
if self.selzooms:
|
||||
if zoom < self.selzooms[0] or zoom > self.selzooms[1]:
|
||||
|
@ -115,9 +132,15 @@ class StyleChooser:
|
|||
#if ftype not in self.compatible_types:
|
||||
#return sl
|
||||
|
||||
object_id = self.testChain(self.ruleChains, ftype, tags, zoom)
|
||||
rule_and_object_id = self.testChain(self.ruleChains, ftype, tags, zoom)
|
||||
|
||||
if not object_id:
|
||||
if not rule_and_object_id:
|
||||
return sl
|
||||
|
||||
rule = rule_and_object_id[0]
|
||||
object_id = rule_and_object_id[1]
|
||||
|
||||
if filter_by_runtime_conditions and (filter_by_runtime_conditions != rule.runtime_conditions):
|
||||
return sl
|
||||
|
||||
for r in self.styles:
|
||||
|
@ -132,7 +155,7 @@ class StyleChooser:
|
|||
for p, q in combined_style.iteritems():
|
||||
if "color" in p:
|
||||
combined_style[p] = cairo_to_hex(q)
|
||||
b = b.compute(tags, combined_style, scale, zscale)
|
||||
b = b.compute(tags, combined_style, xscale, zscale)
|
||||
ra[a] = b
|
||||
ra = make_nice_style(ra)
|
||||
else:
|
||||
|
@ -168,7 +191,7 @@ class StyleChooser:
|
|||
for r in chain:
|
||||
tt = r.test(obj, tags, zoom)
|
||||
if tt:
|
||||
return tt
|
||||
return r, tt
|
||||
return False
|
||||
|
||||
def newGroup(self):
|
||||
|
@ -200,9 +223,16 @@ class StyleChooser:
|
|||
"""
|
||||
adds into the current ruleChain (existing Rule)
|
||||
"""
|
||||
c = OptimizeCondition(c)
|
||||
self.ruleChains[-1].conditions.append(c)
|
||||
|
||||
def addRuntimeCondition(self, c):
|
||||
# print "addRuntimeCondition ", c
|
||||
"""
|
||||
adds into the current ruleChain (existing Rule)
|
||||
"""
|
||||
self.ruleChains[-1].runtime_conditions.append(c)
|
||||
self.ruleChains[-1].runtime_conditions.sort()
|
||||
|
||||
def addStyles(self, a):
|
||||
# print "addStyle ", a
|
||||
"""
|
||||
|
|
|
@ -33,6 +33,7 @@ CLASS = re.compile(r'^ ([\.:]:?[*\w]+) \s* ', re.S | re.X)
|
|||
ZOOM = re.compile(r'^ \| \s* z([\d\-]+) \s* ', re.I | re.S | re.X)
|
||||
GROUP = re.compile(r'^ , \s* ', re.I | re.S | re.X)
|
||||
CONDITION = re.compile(r'^ \[(.+?)\] \s* ', re.S | re.X)
|
||||
RUNTIME_CONDITION = re.compile(r'^ \((.+?)\) \s* ', re.S | re.X)
|
||||
OBJECT = re.compile(r'^ (\*|[\w]+) \s* ', re.S | re.X)
|
||||
DECLARATION = re.compile(r'^ \{(.+?)\} \s* ', re.S | re.X)
|
||||
IMPORT = re.compile(r'^@import\("(.+?)"\); \s* ', re.S | re.X)
|
||||
|
@ -133,15 +134,23 @@ class MapCSS():
|
|||
tmp.append(ec)
|
||||
self.choosers_by_type_and_tag[type][tag] = tmp
|
||||
|
||||
def get_style(self, clname, type, tags={}, zoom=0, scale=1, zscale=.5):
|
||||
def get_runtime_rules(self, clname, type, tags, zoom):
|
||||
"""
|
||||
Kothic styling API
|
||||
Returns array of runtime_conditions which are used for clname/type/tags/zoom
|
||||
"""
|
||||
runtime_rules = []
|
||||
if type in self.choosers_by_type_and_tag:
|
||||
for chooser in self.choosers_by_type_and_tag[type][clname]:
|
||||
runtime_conditions = chooser.get_runtime_conditions(type, tags, zoom)
|
||||
if runtime_conditions:
|
||||
runtime_rules.append(runtime_conditions)
|
||||
return runtime_rules
|
||||
|
||||
def get_style(self, clname, type, tags, zoom, xscale, zscale, filter_by_runtime_conditions):
|
||||
style = []
|
||||
if type in self.choosers_by_type_and_tag:
|
||||
choosers = self.choosers_by_type_and_tag[type][clname]
|
||||
for chooser in choosers:
|
||||
style = chooser.updateStyles(style, type, tags, zoom, scale, zscale)
|
||||
for chooser in self.choosers_by_type_and_tag[type][clname]:
|
||||
style = chooser.updateStyles(style, type, tags, zoom, 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)]:
|
||||
|
@ -155,8 +164,11 @@ class MapCSS():
|
|||
style = st
|
||||
return style
|
||||
|
||||
def get_style_dict(self, clname, type, tags={}, zoom=0, scale=1, zscale=.5, olddict={}):
|
||||
r = self.get_style(clname, type, tags, zoom, scale, zscale)
|
||||
def get_style_dict(self, clname, type, tags={}, zoom=0, xscale=1, zscale=.5, olddict={}, filter_by_runtime_conditions=None):
|
||||
"""
|
||||
Kothic styling API
|
||||
"""
|
||||
r = self.get_style(clname, type, tags, zoom, xscale, zscale, filter_by_runtime_conditions)
|
||||
d = olddict
|
||||
for x in r:
|
||||
if x.get('object-id', '') not in d:
|
||||
|
@ -165,7 +177,7 @@ class MapCSS():
|
|||
return d
|
||||
|
||||
def subst_variables(self, t):
|
||||
"""Expects an array from parseDeclaration."""
|
||||
""" Expects an array from parseDeclaration. """
|
||||
for k in t[0]:
|
||||
t[0][k] = VARIABLE.sub(self.get_variable, t[0][k])
|
||||
return t
|
||||
|
@ -176,7 +188,7 @@ class MapCSS():
|
|||
raise Exception("Variable not found: " + str(format(name)))
|
||||
return self.variables[name] if name in self.variables else m.group()
|
||||
|
||||
def parse(self, css=None, clamp=True, stretch=1000, filename=None):
|
||||
def parse(self, css=None, clamp=True, stretch=1000, filename=None, mapcss_tags=None):
|
||||
"""
|
||||
Parses MapCSS given as string
|
||||
"""
|
||||
|
@ -238,6 +250,19 @@ class MapCSS():
|
|||
sc.newGroup()
|
||||
previous = oGROUP
|
||||
|
||||
# RuntimeCondition - (population>=10000)
|
||||
elif RUNTIME_CONDITION.match(css):
|
||||
if (previous == oDECLARATION):
|
||||
self.choosers.append(sc)
|
||||
sc = StyleChooser(self.scalepair)
|
||||
if (previous != oOBJECT) and (previous != oZOOM) and (previous != oCONDITION):
|
||||
sc.newObject()
|
||||
cond = RUNTIME_CONDITION.match(css).groups()[0]
|
||||
log.debug("runtime condition found: %s" % (cond))
|
||||
css = RUNTIME_CONDITION.sub("", css)
|
||||
sc.addRuntimeCondition(parseCondition(cond))
|
||||
previous = oCONDITION
|
||||
|
||||
# Condition - [highway=primary]
|
||||
elif CONDITION.match(css):
|
||||
if (previous == oDECLARATION):
|
||||
|
@ -247,8 +272,12 @@ class MapCSS():
|
|||
sc.newObject()
|
||||
cond = CONDITION.match(css).groups()[0]
|
||||
log.debug("condition found: %s" % (cond))
|
||||
c = parseCondition(cond)
|
||||
tag = c.extract_tag()
|
||||
if (tag != "*") and (mapcss_tags != None) and (tag not in mapcss_tags):
|
||||
raise Exception("Unknown tag '" + tag + "' in condition " + cond)
|
||||
css = CONDITION.sub("", css)
|
||||
sc.addCondition(parseCondition(cond))
|
||||
sc.addCondition(c)
|
||||
previous = oCONDITION
|
||||
|
||||
# Object - way, node, relation
|
||||
|
|
Loading…
Add table
Reference in a new issue