mapcss -> mapnik enhancements

This commit is contained in:
Komяpa 2010-10-06 09:35:48 +03:00
parent bf6943a9cd
commit bc46da5e2b
3 changed files with 146 additions and 20 deletions

View file

@ -27,8 +27,8 @@ try:
except ImportError:
pass
minzoom = 10
maxzoom = 11
minzoom = 1
maxzoom = 19
style = MapCSS(minzoom, maxzoom) #zoom levels
@ -67,6 +67,31 @@ for zoom, zsheet in mapniksheet.iteritems():
x_scale = xml_scaledenominator(zoom)
ta = zsheet.keys()
ta.sort(key=float)
for zindex in ta:
## areas pass
sql = set()
itags = set()
xml = xml_style_start()
for entry in zsheet[zindex]:
if entry["type"] in ("way", "area", "polygon"):
if "fill-color" in entry["style"]:
xml += xml_rule_start()
xml += x_scale
rulestring = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule]) + ")" for rule in entry["rule"]])
xml += xml_filter(rulestring)
xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), entry["style"].get("fill-opacity", "1"))
sql.update(entry["sql"])
itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom))
xml += xml_rule_end()
sql = [i[1] for i in sql]
xml += xml_style_end()
if sql:
mfile.write(xml)
mfile.write(xml_layer("postgis", "polygon", itags, sql ))
else:
xml_nolayer()
for zindex in ta:
## casings pass
sql = set()
@ -77,10 +102,10 @@ for zoom, zsheet in mapniksheet.iteritems():
if "casing-width" in entry["style"]:
xml += xml_rule_start()
xml += x_scale
rulestring = " or ".join([rule[0].get_mapnik_filter() for rule in entry["rule"]])
rulestring = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule]) + ")" for rule in entry["rule"]])
xml += xml_filter(rulestring)
xml += xml_linesymbolizer(color=entry["style"].get("casing-color", "black"),
width=entry["style"].get("casing-width", "1"),
width=float(entry["style"].get("casing-width", 1))+float(entry["style"].get("width", 0)),
opacity=entry["style"].get("casing-opacity", "1"),
linecap=entry["style"].get("casing-linecap", entry["style"].get("linecap","butt")),
linejoin=entry["style"].get("casing-linejoin", entry["style"].get("linejoin", "round")))
@ -94,19 +119,25 @@ for zoom, zsheet in mapniksheet.iteritems():
mfile.write(xml_layer("postgis", "line", itags, sql ))
else:
xml_nolayer()
## areas pass
for zindex in ta:
## lines pass
sql = set()
itags = set()
xml = xml_style_start()
for entry in zsheet[zindex]:
if entry["type"] in ("way", "area", "polygon"):
if "fill-color" in entry["style"]:
if entry["type"] in ("way", "line"):
if "width" in entry["style"]:
xml += xml_rule_start()
xml += x_scale
rulestring = " or ".join([rule[0].get_mapnik_filter() for rule in entry["rule"]])
rulestring = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule]) + ")" for rule in entry["rule"]])
xml += xml_filter(rulestring)
xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), entry["style"].get("fill-opacity", "1"))
xml += xml_linesymbolizer(color=entry["style"].get("color", "black"),
width=entry["style"].get("width", "1"),
opacity=entry["style"].get("opacity", "1"),
linecap=entry["style"].get("linecap", "butt"),
linejoin=entry["style"].get("linejoin", "round"),
dashes=entry["style"].get("dashes", ""))
sql.update(entry["sql"])
itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom))
xml += xml_rule_end()
@ -114,7 +145,70 @@ for zoom, zsheet in mapniksheet.iteritems():
xml += xml_style_end()
if sql:
mfile.write(xml)
mfile.write(xml_layer("postgis", "polygon", itags, sql ))
mfile.write(xml_layer("postgis", "line", itags, sql ))
else:
xml_nolayer()
for layer_type, entry_types in {"line":("way", "line"), "polygon":("way","area"), "point": ("node", "point")}.iteritems():
for zindex in ta:
## icons pass
sql = set()
itags = set()
xml = xml_style_start()
for entry in zsheet[zindex]:
if entry["type"] in entry_types:
if "icon-image" in entry["style"]:
xml += xml_rule_start()
xml += x_scale
rulestring = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule]) + ")" for rule in entry["rule"]])
xml += xml_filter(rulestring)
xml += xml_pointsymbolizer(
path=entry["style"].get("icon-image", ""),
width=entry["style"].get("icon-width", ""),
height=entry["style"].get("icon-height", ""),
opacity=entry["style"].get("opacity", "1"))
sql.update(entry["sql"])
itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom))
xml += xml_rule_end()
sql = [i[1] for i in sql]
xml += xml_style_end()
if sql:
mfile.write(xml)
mfile.write(xml_layer("postgis", layer_type, itags, sql ))
else:
xml_nolayer()
for layer_type, entry_types in {"line":("way", "line"), "polygon":("way","area"), "point": ("node", "point")}.iteritems():
for zindex in ta:
## text pass
sql = set()
itags = set()
xml = xml_style_start()
for entry in zsheet[zindex]:
if entry["type"] in entry_types:#, "node", "line", "point"):
if "text" in entry["style"]:
ttext = entry["style"]["text"].extract_tags().pop()
tface = entry["style"].get("font-family","DejaVu Sans Book")
tsize = entry["style"].get("font-size","10")
tcolor = entry["style"].get("text-color","#000000")
thcolor= entry["style"].get("text-halo-color","#ffffff")
thradius= entry["style"].get("text-halo-radius","0")
tplace= entry["style"].get("text-position","center")
toffset= entry["style"].get("text-offset","0")
xml += xml_rule_start()
xml += x_scale
rulestring = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule]) + ")" for rule in entry["rule"]])
xml += xml_filter(rulestring)
xml += xml_textsymbolizer(ttext,tface,tsize,tcolor, thcolor, thradius, tplace, toffset)
sql.update(entry["sql"])
itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom))
xml += xml_rule_end()
sql = [i[1] for i in sql]
xml += xml_style_end()
if sql:
mfile.write(xml)
mfile.write(xml_layer("postgis", layer_type, itags, sql ))
else:
xml_nolayer()
mfile.write(xml_end())

View file

@ -26,6 +26,9 @@ db_proj = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0
table_prefix = "planet_osm_"
db_user = "gis"
db_name = "gis"
db_srid = 900913
icons_path = "/home/gis/mapnik/kosmo/icons/"
substyles = []
@ -46,15 +49,29 @@ def zoom_to_scaledenom(z1,z2=False):
if not z2:
z2 = z1
s = 279541132.014
z1 = s/(2**z1-1)+100
z2 = s/(2**z2-1)-100
return 100000000000000, 1
z1 = (s/(2**(z1-1))+s/(2**(z1-2)))/2
z2 = (s/(2**(z2-1))+s/(2**z2))/2
#return 100000000000000, 1
return z1, z2
def xml_pointsymbolizer(path="", width="", height="", opacity=1, overlap="false"):
if width:
width =' width="%s" '%width
if height:
height =' height="%s" '%height
return """
<PointSymbolizer file="%s%s" %s %s opacity="%s" allow_overlap="%s" />"""\
%(icons_path, \
path, width, height, opacity, overlap)
def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt", linejoin="round"):
def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt", linejoin="round", dashes=""):
color = nicecolor(color)
linecap = {"none":"butt",}.get(linecap.lower(), linecap)
if dashes:
dashes = '<CssParameter name="stroke-dasharray">%s</CssParameter>'%(dashes)
else:
dashes = ""
return """
<LineSymbolizer>
<CssParameter name="stroke">%s</CssParameter>
@ -62,7 +79,8 @@ def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt",
<CssParameter name="stroke-opacity">%s</CssParameter>
<CssParameter name="stroke-linejoin">%s</CssParameter>
<CssParameter name="stroke-linecap">%s</CssParameter>
</LineSymbolizer>"""%(color, float(width), float(opacity), linejoin, linecap)
%s
</LineSymbolizer>"""%(color, float(width), float(opacity), linejoin, linecap, dashes)
def xml_polygonsymbolizer(color="#000000", opacity="1"):
@ -74,6 +92,14 @@ def xml_polygonsymbolizer(color="#000000", opacity="1"):
<CssParameter name="fill-opacity">%s</CssParameter>
</PolygonSymbolizer>"""%(color, float(opacity))
def xml_textsymbolizer(text="name",face="DejaVu Sans Book",size="10",color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0"):
color = nicecolor(color)
halo_color = nicecolor(halo_color)
placement = {"center": "point"}.get(placement.lower(), placement)
return """
<TextSymbolizer name="%s" face_name="%s" size="%s" fill="%s" halo_fill= "%s" halo_radius="%s" placement="%s" allow_overlap="false" dy="%s"/>
"""%(text,face,size,color,halo_color,halo_radius,placement,offset)
def xml_filter(string):
return """
<Filter>%s</Filter>"""%string
@ -117,7 +143,7 @@ def xml_rule_end():
</Rule>"""
def xml_layer(type="postgis", geom="point", interesting_tags = "*", sql = ["true","d"] ):
def xml_layer(type="postgis", geom="point", interesting_tags = "*", sql = ["true"] ):
layer_id = get_id(1) ## increment by 0 - was incremented in style
interesting_tags = "\", \"".join(interesting_tags)
interesting_tags = "\""+ interesting_tags+"\""
@ -139,8 +165,12 @@ def xml_layer(type="postgis", geom="point", interesting_tags = "*", sql = ["true
<Parameter name="type">postgis</Parameter>
<Parameter name="user">%s</Parameter>
<Parameter name="dbname">%s</Parameter>
<Parameter name="srid">%s</Parameter>
<Parameter name="geometry_field">way</Parameter>
<Parameter name="geometry_table">%s%s</Parameter>
<Parameter name="extent">-20037508.342789244, -20037508.342780735, 20037508.342789244, 20037508.342780709</Parameter>
</Datasource>
</Layer>"""%(layer_id, db_proj, subs, interesting_tags, table_prefix, geom, sql, db_user, db_name)
</Layer>"""%(layer_id, db_proj, subs, interesting_tags, table_prefix, geom, sql, db_user, db_name, db_srid, table_prefix, geom)
def xml_nolayer():
global substyles

View file

@ -73,7 +73,8 @@ class Condition:
return False;
def get_sql(self):
params = [re.escape(x) for x in self.params]
#params = [re.escape(x) for x in self.params]
params = self.params
t = self.type
try:
if t == 'eq':
@ -102,7 +103,8 @@ class Condition:
except KeyError:
pass
def get_mapnik_filter(self):
params = [re.escape(x) for x in self.params]
#params = [re.escape(x) for x in self.params]
params = self.params
t = self.type
try:
if t == 'eq':