diff --git a/src/make_postgis_style.py b/src/make_postgis_style.py index 8f07e26..dccd26c 100644 --- a/src/make_postgis_style.py +++ b/src/make_postgis_style.py @@ -15,23 +15,34 @@ # You should have received a copy of the GNU General Public License # along with kothic. If not, see . +import sys from debug import debug, Timer from mapcss import MapCSS -style = MapCSS(1, 19) #zoom levels -style.parse(open("styles/osmosnimki-maps.mapcss","r").read()) -t = ("way", "node") +langs = ['int_name', 'name:af', 'name:am', 'name:ar', 'name:be', 'name:bg', 'name:br', 'name:ca', 'name:cs', 'name:cy', 'name:de', 'name:el', 'name:en', 'name:eo', 'name:es', 'name:et', 'name:eu', 'name:fa', 'name:fi', 'name:fr', 'name:fur', 'name:fy', 'name:ga', 'name:gd', 'name:gsw', 'name:he', 'name:hi', 'name:hr', 'name:hsb', 'name:hu', 'name:hy', 'name:it', 'name:ja', 'name:ja_kana', 'name:ja_rm', 'name:ka', 'name:kk', 'name:kn', 'name:ko', 'name:ko_rm', 'name:ku', 'name:la', 'name:lb', 'name:lt', 'name:lv', 'name:mk', 'name:mn', 'name:nl', 'name:pl', 'name:pt', 'name:ro', 'name:ru', 'name:sk', 'name:sl', 'name:sq', 'name:sr', 'name:sv', 'name:th', 'name:tr', 'name:uk', 'name:vi', 'name:zh', 'name:zh_pinyin'] + +if len(sys.argv) < 2: + print "Usage: make_postgis_style.py [stylesheet] [additional_tag,tag2,tag3]" + exit() + +style = MapCSS(1, 19) #zoom levels +style.parse(open(sys.argv[1],"r").read()) + dct = {} +if len(sys.argv) >= 3: + langs.extend(sys.argv[2].split(",")) + dct = dict([(k,set([("node", "linear"), ('way', 'linear')])) for k in langs]) + +t = {"node":("node", "linear"), "line":("way", "linear"), "area":("way", "polygon")} + for a in t: for tag in style.get_interesting_tags(type=a): if tag not in dct: dct[tag] = set() - dct[tag].add(a) - - + dct[tag].add(t[a]) print """ # OsmType Tag DataType Flags""" @@ -39,13 +50,16 @@ for t in ("z_order","way_area",":area"): if t in dct: del dct[t] -for k,v in dct.iteritems(): - s = "" - for i in v: - s += i - s += "," - s = s[:-1] - print "%-10s %-18s %-13s %s"%(s, k, "text", "polygon") +keys = dct.keys() +keys.sort() + +for k in keys: + v = dct[k] + s = ",".join(set([i[0] for i in v])) + pol = "linear" + if "polygon" in set([i[1] for i in v]): + pol = "polygon" + print "%-10s %-20s %-13s %s"%(s, k, "text", pol) print """ -node,way z_order int4 linear # This is calculated during import -way way_area real # This is calculated during import""" +node,way z_order int4 linear # This is calculated during import +way way_area real # This is calculated during import""" diff --git a/src/mapcss/Rule.py b/src/mapcss/Rule.py index 7c49852..691fce1 100644 --- a/src/mapcss/Rule.py +++ b/src/mapcss/Rule.py @@ -53,25 +53,28 @@ class Rule(): def get_interesting_tags(self, obj, zoom): if obj: - if (self.subject!='') and not _test_feature_compatibility(obj, self.subject, {}): + if (self.subject != '') and not _test_feature_compatibility(obj, self.subject, {}): return set() - if not self.test_zoom(zoom): + + if zoom and not self.test_zoom(zoom): return set() + a = set() for condition in self.conditions: a.update(condition.get_interesting_tags()) return a + def get_numerics(self): a = set() for condition in self.conditions: a.add(condition.get_numerics()) a.discard(False) return a + def get_sql_hints(self, obj, zoom): if obj: if (self.subject!='') and not _test_feature_compatibility(obj, self.subject, {":area":"yes"}): return set() - if not self.test_zoom(zoom): return set() a = set() @@ -85,13 +88,10 @@ class Rule(): b = " AND ".join(b) return a,b - - def _test_feature_compatibility (f1, f2, tags={}): """ Checks if feature of type f1 is compatible with f2. """ - if f2 == f1: return True elif f2 == "way" and f1 == "line": @@ -99,14 +99,14 @@ def _test_feature_compatibility (f1, f2, tags={}): elif f2 == "way" and f1 == "area": return True elif f2 == "area" and f1 in ("way", "area", "POLYGON"): - if ":area" in tags: - pass - else: - return False +# if ":area" in tags: + return True +# else: +# return False elif f2 == "line" and f1 in ("way", "line", "LINESTRING"): - pass + return True elif f2 == "point" and f1 in ("node", "POINT"): - pass + return True else: return False #print f1, f2, True diff --git a/src/mapcss/__init__.py b/src/mapcss/__init__.py index 4b7489d..09e16e8 100644 --- a/src/mapcss/__init__.py +++ b/src/mapcss/__init__.py @@ -114,12 +114,74 @@ class MapCSS(): return float(ZOOM_SINGLE.match(s).groups()[0]),float(ZOOM_SINGLE.match(s).groups()[0]) else: logging.error("unparsed zoom: %s" %s) + def precompile_style (self): + # TODO: styleshees precompilation + + subjs = {"canvas": ("canvas",),"way": ("Polygon","LineString"), "line":("Polygon","LineString"), "area": ("Polygon",), "node": ("Point",), "*":("Point","Polygon","LineString") } + mfile.write("function restyle (prop, zoom, type){") + mfile.write("style = new Object;") + mfile.write('style["default"] = new Object;') + for chooser in style.choosers: + condition = "" + subclass = "default" + for i in chooser.ruleChains[0]: + if condition: + condition += "||" + rule = " zoom >= %s && zoom <= %s"%(i.minZoom, i.maxZoom) + for z in i.conditions: + t = z.type + params = z.params + if params[0] == "::class": + subclass = params[1][2:] + continue + if rule: + rule += " && " + if t == 'eq': + rule += 'prop["%s"] == "%s"'%(params[0], params[1]) + if t == 'ne': + rule += 'prop["%s"] != "%s"'%(params[0], params[1]) + if t == 'regex': + rule += 'prop["%s"].match(RegExp("%s"))'%(params[0], params[1]) + if t == 'true': + rule += 'prop["%s"] == "yes"'%(params[0]) + if t == 'untrue': + rule += 'prop["%s"] != "yes"'%(params[0]) + if t == 'set': + rule += '"%s" in prop'%(params[0]) + if t == 'unset': + rule += '!("%s"in prop)'%(params[0]) + if t == '<': + rule += 'prop["%s"] < %s'%(params[0], params[1]) + if t == '<=': + rule += 'prop["%s"] <= %s'%(params[0], params[1]) + if t == '>': + rule += 'prop["%s"] > %s'%(params[0], params[1]) + if t == '>=': + rule += 'prop["%s"] >= %s'%(params[0], params[1]) + if rule: + rule = "&&" + rule + condition += "(("+"||".join(['type == "%s"'%z for z in subjs[i.subject]])+") "+ rule + ")" + #print chooser.styles + styles = "" + #if subclass != "default": + #styles = 'if(!("%s" in style)){style["%s"] = new Object;}'%(subclass,subclass) + #for k, v in chooser.styles[0].iteritems(): + + if type(v) == str: + try: + v = str(float(v)) + styles += 'style["'+subclass+'"]["'+k+'"] = '+v + ';' + except: + styles += 'style["'+subclass+'"]["'+k+'"] = "' + v + '";' + + mfile.write("if(%s) {%s};\n"%(condition,styles)) + mfile.write("return style;}") def get_style (self, type, tags={}, zoom=0, scale=1, zscale=.5): """ Kothic styling API """ - shash = md5(repr(tags)+repr(zoom)).digest() + shash = md5(repr(type)+repr(tags)+repr(zoom)).digest() if shash in self.cache["style"]: return self.cache["style"][shash] style = [] @@ -138,13 +200,13 @@ class MapCSS(): for chooser in self.choosers: tags.update(chooser.get_interesting_tags(type, zoom)) return tags + def get_sql_hints(self, type=None, zoom=None): """ Get set of interesting tags. """ hints = [] for chooser in self.choosers: - p = chooser.get_sql_hints(type, zoom) if p: if p[0] and p[1]: diff --git a/src/mapcss/webcolors/webcolors.py b/src/mapcss/webcolors/webcolors.py index 7b7a47b..f3641ba 100644 --- a/src/mapcss/webcolors/webcolors.py +++ b/src/mapcss/webcolors/webcolors.py @@ -616,6 +616,13 @@ def hex_to_name(hex_value, spec='css3'): raise ValueError("'%s' has no defined color name in %s." % (hex_value, spec)) return name +def any_hex_to_name(hex_value): + try: + return hex_to_name(hex_value) + except ValueError: + return hex_value + + def hex_to_rgb(hex_value): """ Convert a hexadecimal color value to a 3-tuple of integers @@ -826,15 +833,6 @@ def rgb_percent_to_rgb(rgb_percent_triplet): - - - - - - - - - def whatever_to_rgb(string): """ Converts CSS3 color or a hex into rgb triplet; hash of string if fails. @@ -849,14 +847,13 @@ def whatever_to_rgb(string): try: if string[:3] == "rgb": return tuple([float(i) for i in string[4:-1].split(",")][0:3]) - except: return hex_to_rgb("#"+md5(string).hexdigest()[:6]) def whatever_to_hex(string): if type(string) == tuple: - return cairo_to_hex(string) - return rgb_to_hex(whatever_to_rgb(string)) + return cairo_to_hex(string).upper() + return rgb_to_hex(whatever_to_rgb(string)).upper() def whatever_to_cairo(string): a = whatever_to_rgb(string) return a[0]/255.,a[1]/255.,a[2]/255.,