diff --git a/src/backend/postgis/__init__.py b/src/backend/postgis/__init__.py index 02c012e..f8e2f0a 100644 --- a/src/backend/postgis/__init__.py +++ b/src/backend/postgis/__init__.py @@ -15,10 +15,12 @@ # You should have received a copy of the GNU General Public License # along with kothic. If not, see . -#from debug import debug +# from debug import debug from twms import projections import psycopg2 import shapely.wkb + + class Empty: def copy(self): a = Empty() @@ -33,18 +35,18 @@ class Way: def __init__(self, tags, geom): self.cs = [] - #print [x.split("=") for x in tags.split(";")] + # print [x.split("=") for x in tags.split(";")] self.tags = tags # calculating center point - #c= geom - #sumz = [(c[0],c[1])] - #for k in range(2, len(c), 2): + # c= geom + # sumz = [(c[0],c[1])] + # for k in range(2, len(c), 2): # sumz.append((c[k], c[k + 1])) self.coords = geom # left for the better times: - self.center = reduce(lambda x, y: (x[0]+y[0],x[1]+y[1]), self.coords) - self.center = (self.center[0]/len(self.coords),self.center[1]/len(self.coords)) - #debug(self.center) + self.center = reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), self.coords) + self.center = (self.center[0] / len(self.coords), self.center[1] / len(self.coords)) + # debug(self.center) def copy(self): a = Empty() @@ -54,17 +56,16 @@ class Way: a.cs = self.cs[:] return a + class PostGisBackend: """ A class that gives out vector data on demand. """ - - def __init__(self,database = "dbname=gis user=mapz host=komzpa.net",max_zoom = 16,proj = "EPSG:3857", path = "tiles", lang = "ru", ): - + def __init__(self, database="dbname=gis user=mapz host=komzpa.net", max_zoom=16, proj="EPSG:3857", path="tiles", lang="ru", ): # debug("Bakend created") - self.database=database + self.database = database self.max_zoom = max_zoom # no better tiles available self.path = path # path to tile files self.lang = lang # map language to use @@ -73,16 +74,16 @@ class PostGisBackend: self.keep_tiles = 190 # a number of tiles to cache in memory self.tile_load_log = [] # used when selecting which tile to unload - def get_vectors (self, bbox, zoom, sql_hint = None, tags_hint = None): + def get_vectors(self, bbox, zoom, sql_hint=None, tags_hint=None): """ Fetches vectors for given bbox. sql_hint is a list of sets of (key, sql_for_key) """ a = psycopg2.connect(self.database) b = a.cursor() - bbox = tuple(projections.from4326(bbox,self.proj)) + bbox = tuple(projections.from4326(bbox, self.proj)) ### FIXME: hardcoded EPSG:3857 in database - tables = ("planet_osm_line","planet_osm_polygon") # FIXME: points + tables = ("planet_osm_line", "planet_osm_polygon") # FIXME: points resp = {} for table in tables: add = "" @@ -92,7 +93,7 @@ class PostGisBackend: for tp in sql_hint: add = [] - b.execute("SELECT * FROM %s LIMIT 1;"%table) + b.execute("SELECT * FROM %s LIMIT 1;" % table) names = [q[0] for q in b.description] for j in tp[0]: @@ -102,25 +103,23 @@ class PostGisBackend: add.append(tp[1]) if add: add = " OR ".join(add) - add = "("+add+")" + add = "(" + add + ")" adp.append(add) if tags_hint: - taghint = ", ".join(['"'+j+'"' for j in tags_hint if j in names])+ ", way, osm_id" - + taghint = ", ".join(['"' + j + '"' for j in tags_hint if j in names]) + ", way, osm_id" adp = " OR ".join(adp) - - req = "SELECT %s FROM %s WHERE (%s) and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913);"%(taghint,table,adp,bbox[0],bbox[1],bbox[2],bbox[3]) + req = "SELECT %s FROM %s WHERE (%s) and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913);" % (taghint, table, adp, bbox[0], bbox[1], bbox[2], bbox[3]) print req b.execute(req) names = [q[0] for q in b.description] for row in b.fetchall(): - row_dict = dict(map(None,names,row)) - for k,v in row_dict.items(): + row_dict = dict(map(None, names, row)) + for k, v in row_dict.items(): if not v: del row_dict[k] geom = shapely.wkb.loads(row_dict["way"].decode('hex')) @@ -138,12 +137,12 @@ class PostGisBackend: continue ### FIXME - #geom = projections.to4326(geom, self.proj) + # geom = projections.to4326(geom, self.proj) del row_dict["way"] oid = row_dict["osm_id"] del row_dict["osm_id"] w = Way(row_dict, geom) - #print row_dict + # print row_dict resp[oid] = w a.close() del a diff --git a/src/backend/vtile/__init__.py b/src/backend/vtile/__init__.py index e86ce93..1160fe2 100644 --- a/src/backend/vtile/__init__.py +++ b/src/backend/vtile/__init__.py @@ -19,6 +19,7 @@ from twms import projections import twms.bbox + class Empty: def copy(self): a = Empty() @@ -29,23 +30,25 @@ class Empty: a.bbox = self.bbox return a + class Way: def __init__(self, tags, coords): self.cs = [] - #print [x.split("=") for x in tags.split(";")] + # print [x.split("=") for x in tags.split(";")] self.tags = dict((x.split("=") for x in tags.split(";"))) # calculating center point - c= coords - sumz = [(c[0],c[1])] + c = coords + sumz = [(c[0], c[1])] for k in range(2, len(c), 2): sumz.append((c[k], c[k + 1])) self.coords = sumz # left for the better times: - self.center = reduce(lambda x, y: (x[0]+y[0],x[1]+y[1]), self.coords) - self.center = (self.center[0]/len(self.coords),self.center[1]/len(self.coords)) - self.bbox = reduce(lambda x,y: (min(x[0],y[0]),min(x[1],y[1]),max(x[2],y[0]),max(x[3],y[1])), self.coords, (9999,9999,-9999,-9999)) - #debug(self.center) + self.center = reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), self.coords) + self.center = (self.center[0] / len(self.coords), self.center[1] / len(self.coords)) + self.bbox = reduce(lambda x, y: (min(x[0], y[0]), min(x[1], y[1]), max(x[2], y[0]), max(x[3], y[1])), self.coords, (9999, 9999, -9999, -9999)) + # debug(self.center) + def copy(self): a = Empty() a.tags = self.tags.copy() @@ -61,9 +64,7 @@ class QuadTileBackend: A class that gives out vector data on demand. """ - - def __init__(self,max_zoom = 16,proj = "EPSG:4326", path = "tiles", lang = "ru"): - + def __init__(self, max_zoom=16, proj="EPSG:4326", path="tiles", lang="ru"): self.max_zoom = max_zoom # no better tiles available self.path = path # path to tile files @@ -73,52 +74,53 @@ class QuadTileBackend: self.keep_tiles = 15 # a number of tiles to cache in memory self.tile_load_log = [] # used when selecting which tile to unload + def filename(self, (z, x, y)): - def filename(self, (z,x,y)): + return "%s/z%s/%s/x%s/%s/y%s.vtile" % (self.path, z, x / 1024, x, y / 1024, y) - return "%s/z%s/%s/x%s/%s/y%s.vtile"%(self.path, z, x/1024, x, y/1024, y) def load_tile(self, k): - #debug("loading tile: %s"% (k,)) + # debug("loading tile: %s"% (k,)) try: f = open(self.filename(k)) except IOError: - print ( "Failed open: '%s'" % self.filename(k) ) + print ("Failed open: '%s'" % self.filename(k)) return {} t = {} for line in f: - #debug(line) + # debug(line) a = line.split(" ") w = Way(a[0], [float(x) for x in a[2:]]) t[int(a[1])] = w f.close() return t + def collect_garbage(self): """ Cleans up some RAM by removing least accessed tiles. """ if len(self.tiles) > self.keep_tiles: - #debug("Now %s tiles cached, trying to kill %s"%(len(self.tiles),len(self.tiles)-self.keep_tiles)) - for tile in self.tile_load_log[0:len(self.tiles)-self.keep_tiles]: + # debug("Now %s tiles cached, trying to kill %s"%(len(self.tiles),len(self.tiles)-self.keep_tiles)) + for tile in self.tile_load_log[0:len(self.tiles) - self.keep_tiles]: try: del self.tiles[tile] self.tile_load_log.remove(tile) - #debug ("killed tile: %s" % (tile,)) + # debug ("killed tile: %s" % (tile,)) except KeyError, ValueError: pass - #debug ("tile killed not by us: %s" % (tile,)) + # debug ("tile killed not by us: %s" % (tile,)) - def get_vectors (self, bbox, zoom, sql_hint = None, itags = None): + def get_vectors(self, bbox, zoom, sql_hint=None, itags=None): zoom = int(zoom) - zoom = min(zoom, self.max_zoom) ## If requested zoom is better than the best, take the best - zoom = max(zoom, 0) ## Negative zooms are nonsense - a,d,c,b = [int(x) for x in projections.tile_by_bbox(bbox,zoom, self.proj)] + zoom = min(zoom, self.max_zoom) # If requested zoom is better than the best, take the best + zoom = max(zoom, 0) # Negative zooms are nonsense + a, d, c, b = [int(x) for x in projections.tile_by_bbox(bbox, zoom, self.proj)] resp = {} hint = set() for j in [x[0] for x in sql_hint]: hint.update(j) - for tile in set([(zoom,i,j) for i in range(a, c+1) for j in range(b, d+1)]): + for tile in set([(zoom, i, j) for i in range(a, c + 1) for j in range(b, d + 1)]): # Loading current vector tile try: ti = self.tiles[tile] @@ -135,7 +137,7 @@ class QuadTileBackend: "filling response with interesting-tagged objects" need = False for tag in ti[obj].tags: - #if tag in hint: + # if tag in hint: need = True break if need: diff --git a/src/debug.py b/src/debug.py index 1065a7b..a324ffc 100644 --- a/src/debug.py +++ b/src/debug.py @@ -17,16 +17,16 @@ import datetime import sys + def debug(st): """ Debug write to stderr """ - sys.stderr.write(str(st)+"\n") + sys.stderr.write(str(st) + "\n") sys.stderr.flush() - class Timer: """ A small timer for debugging @@ -35,5 +35,6 @@ class Timer: self.time = datetime.datetime.now() self.comment = comment debug("%s started" % comment) + def stop(self): debug("%s finished in %s" % (self.comment, str(datetime.datetime.now() - self.time))) diff --git a/src/drules_struct_pb2.py b/src/drules_struct_pb2.py index 8276fc6..47d1db5 100644 --- a/src/drules_struct_pb2.py +++ b/src/drules_struct_pb2.py @@ -7,61 +7,60 @@ from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) - DESCRIPTOR = descriptor.FileDescriptor( - name='drules_struct.proto', - package='', - serialized_pb='\n\x13\x64rules_struct.proto\"*\n\x0c\x44\x61shDotProto\x12\n\n\x02\x64\x64\x18\x01 \x03(\x01\x12\x0e\n\x06offset\x18\x02 \x01(\x01\":\n\x0cPathSymProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04step\x18\x02 \x02(\x01\x12\x0e\n\x06offset\x18\x03 \x01(\x01\"\xaf\x01\n\rLineRuleProto\x12\r\n\x05width\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1e\n\x07\x64\x61shdot\x18\x03 \x01(\x0b\x32\r.DashDotProto\x12\x10\n\x08priority\x18\x04 \x02(\x05\x12\x1e\n\x07pathsym\x18\x05 \x01(\x0b\x32\r.PathSymProto\x12\x17\n\x04join\x18\x06 \x01(\x0e\x32\t.LineJoin\x12\x15\n\x03\x63\x61p\x18\x07 \x01(\x0e\x32\x08.LineCap\"\x9c\x01\n\x0cLineDefProto\x12\r\n\x05width\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1e\n\x07\x64\x61shdot\x18\x03 \x01(\x0b\x32\r.DashDotProto\x12\x1e\n\x07pathsym\x18\x04 \x01(\x0b\x32\r.PathSymProto\x12\x17\n\x04join\x18\x06 \x01(\x0e\x32\t.LineJoin\x12\x15\n\x03\x63\x61p\x18\x07 \x01(\x0e\x32\x08.LineCap\"O\n\rAreaRuleProto\x12\r\n\x05\x63olor\x18\x01 \x02(\r\x12\x1d\n\x06\x62order\x18\x02 \x01(\x0b\x32\r.LineDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"I\n\x0fSymbolRuleProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x16\n\x0e\x61pply_for_type\x18\x02 \x01(\x05\x12\x10\n\x08priority\x18\x03 \x02(\x05\"j\n\x0f\x43\x61ptionDefProto\x12\x0e\n\x06height\x18\x01 \x02(\x05\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x14\n\x0cstroke_color\x18\x03 \x01(\r\x12\x10\n\x08offset_x\x18\x04 \x01(\x05\x12\x10\n\x08offset_y\x18\x05 \x01(\x05\"l\n\x10\x43\x61ptionRuleProto\x12!\n\x07primary\x18\x01 \x02(\x0b\x32\x10.CaptionDefProto\x12#\n\tsecondary\x18\x02 \x01(\x0b\x32\x10.CaptionDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"a\n\x0f\x43ircleRuleProto\x12\x0e\n\x06radius\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1d\n\x06\x62order\x18\x03 \x01(\x0b\x32\r.LineDefProto\x12\x10\n\x08priority\x18\x04 \x02(\x05\"m\n\x11PathTextRuleProto\x12!\n\x07primary\x18\x01 \x02(\x0b\x32\x10.CaptionDefProto\x12#\n\tsecondary\x18\x02 \x01(\x0b\x32\x10.CaptionDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"\xed\x01\n\x10\x44rawElementProto\x12\r\n\x05scale\x18\x01 \x02(\x05\x12\x1d\n\x05lines\x18\x02 \x03(\x0b\x32\x0e.LineRuleProto\x12\x1c\n\x04\x61rea\x18\x03 \x01(\x0b\x32\x0e.AreaRuleProto\x12 \n\x06symbol\x18\x04 \x01(\x0b\x32\x10.SymbolRuleProto\x12\"\n\x07\x63\x61ption\x18\x05 \x01(\x0b\x32\x11.CaptionRuleProto\x12 \n\x06\x63ircle\x18\x06 \x01(\x0b\x32\x10.CircleRuleProto\x12%\n\tpath_text\x18\x07 \x01(\x0b\x32\x12.PathTextRuleProto\"G\n\x13\x43lassifElementProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\"\n\x07\x65lement\x18\x02 \x03(\x0b\x32\x11.DrawElementProto\"4\n\x0e\x43ontainerProto\x12\"\n\x04\x63ont\x18\x01 \x03(\x0b\x32\x14.ClassifElementProto*4\n\x08LineJoin\x12\r\n\tROUNDJOIN\x10\x00\x12\r\n\tBEVELJOIN\x10\x01\x12\n\n\x06NOJOIN\x10\x02*3\n\x07LineCap\x12\x0c\n\x08ROUNDCAP\x10\x00\x12\x0b\n\x07\x42UTTCAP\x10\x01\x12\r\n\tSQUARECAP\x10\x02\x42\x02H\x03') + name='drules_struct.proto', + package='', + serialized_pb='\n\x13\x64rules_struct.proto\"*\n\x0c\x44\x61shDotProto\x12\n\n\x02\x64\x64\x18\x01 \x03(\x01\x12\x0e\n\x06offset\x18\x02 \x01(\x01\":\n\x0cPathSymProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04step\x18\x02 \x02(\x01\x12\x0e\n\x06offset\x18\x03 \x01(\x01\"\xaf\x01\n\rLineRuleProto\x12\r\n\x05width\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1e\n\x07\x64\x61shdot\x18\x03 \x01(\x0b\x32\r.DashDotProto\x12\x10\n\x08priority\x18\x04 \x02(\x05\x12\x1e\n\x07pathsym\x18\x05 \x01(\x0b\x32\r.PathSymProto\x12\x17\n\x04join\x18\x06 \x01(\x0e\x32\t.LineJoin\x12\x15\n\x03\x63\x61p\x18\x07 \x01(\x0e\x32\x08.LineCap\"\x9c\x01\n\x0cLineDefProto\x12\r\n\x05width\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1e\n\x07\x64\x61shdot\x18\x03 \x01(\x0b\x32\r.DashDotProto\x12\x1e\n\x07pathsym\x18\x04 \x01(\x0b\x32\r.PathSymProto\x12\x17\n\x04join\x18\x06 \x01(\x0e\x32\t.LineJoin\x12\x15\n\x03\x63\x61p\x18\x07 \x01(\x0e\x32\x08.LineCap\"O\n\rAreaRuleProto\x12\r\n\x05\x63olor\x18\x01 \x02(\r\x12\x1d\n\x06\x62order\x18\x02 \x01(\x0b\x32\r.LineDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"I\n\x0fSymbolRuleProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x16\n\x0e\x61pply_for_type\x18\x02 \x01(\x05\x12\x10\n\x08priority\x18\x03 \x02(\x05\"j\n\x0f\x43\x61ptionDefProto\x12\x0e\n\x06height\x18\x01 \x02(\x05\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x14\n\x0cstroke_color\x18\x03 \x01(\r\x12\x10\n\x08offset_x\x18\x04 \x01(\x05\x12\x10\n\x08offset_y\x18\x05 \x01(\x05\"l\n\x10\x43\x61ptionRuleProto\x12!\n\x07primary\x18\x01 \x02(\x0b\x32\x10.CaptionDefProto\x12#\n\tsecondary\x18\x02 \x01(\x0b\x32\x10.CaptionDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"a\n\x0f\x43ircleRuleProto\x12\x0e\n\x06radius\x18\x01 \x02(\x01\x12\r\n\x05\x63olor\x18\x02 \x02(\r\x12\x1d\n\x06\x62order\x18\x03 \x01(\x0b\x32\r.LineDefProto\x12\x10\n\x08priority\x18\x04 \x02(\x05\"m\n\x11PathTextRuleProto\x12!\n\x07primary\x18\x01 \x02(\x0b\x32\x10.CaptionDefProto\x12#\n\tsecondary\x18\x02 \x01(\x0b\x32\x10.CaptionDefProto\x12\x10\n\x08priority\x18\x03 \x02(\x05\"\xed\x01\n\x10\x44rawElementProto\x12\r\n\x05scale\x18\x01 \x02(\x05\x12\x1d\n\x05lines\x18\x02 \x03(\x0b\x32\x0e.LineRuleProto\x12\x1c\n\x04\x61rea\x18\x03 \x01(\x0b\x32\x0e.AreaRuleProto\x12 \n\x06symbol\x18\x04 \x01(\x0b\x32\x10.SymbolRuleProto\x12\"\n\x07\x63\x61ption\x18\x05 \x01(\x0b\x32\x11.CaptionRuleProto\x12 \n\x06\x63ircle\x18\x06 \x01(\x0b\x32\x10.CircleRuleProto\x12%\n\tpath_text\x18\x07 \x01(\x0b\x32\x12.PathTextRuleProto\"G\n\x13\x43lassifElementProto\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\"\n\x07\x65lement\x18\x02 \x03(\x0b\x32\x11.DrawElementProto\"4\n\x0e\x43ontainerProto\x12\"\n\x04\x63ont\x18\x01 \x03(\x0b\x32\x14.ClassifElementProto*4\n\x08LineJoin\x12\r\n\tROUNDJOIN\x10\x00\x12\r\n\tBEVELJOIN\x10\x01\x12\n\n\x06NOJOIN\x10\x02*3\n\x07LineCap\x12\x0c\n\x08ROUNDCAP\x10\x00\x12\x0b\n\x07\x42UTTCAP\x10\x01\x12\r\n\tSQUARECAP\x10\x02\x42\x02H\x03') _LINEJOIN = descriptor.EnumDescriptor( - name='LineJoin', - full_name='LineJoin', - filename=None, - file=DESCRIPTOR, - values=[ - descriptor.EnumValueDescriptor( - name='ROUNDJOIN', index=0, number=0, - options=None, - type=None), - descriptor.EnumValueDescriptor( - name='BEVELJOIN', index=1, number=1, - options=None, - type=None), - descriptor.EnumValueDescriptor( - name='NOJOIN', index=2, number=2, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=1415, - serialized_end=1467, + name='LineJoin', + full_name='LineJoin', + filename=None, + file=DESCRIPTOR, + values=[ + descriptor.EnumValueDescriptor( + name='ROUNDJOIN', index=0, number=0, + options=None, + type=None), + descriptor.EnumValueDescriptor( + name='BEVELJOIN', index=1, number=1, + options=None, + type=None), + descriptor.EnumValueDescriptor( + name='NOJOIN', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=1415, + serialized_end=1467, ) _LINECAP = descriptor.EnumDescriptor( - name='LineCap', - full_name='LineCap', - filename=None, - file=DESCRIPTOR, - values=[ - descriptor.EnumValueDescriptor( - name='ROUNDCAP', index=0, number=0, - options=None, - type=None), - descriptor.EnumValueDescriptor( - name='BUTTCAP', index=1, number=1, - options=None, - type=None), - descriptor.EnumValueDescriptor( - name='SQUARECAP', index=2, number=2, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=1469, - serialized_end=1520, + name='LineCap', + full_name='LineCap', + filename=None, + file=DESCRIPTOR, + values=[ + descriptor.EnumValueDescriptor( + name='ROUNDCAP', index=0, number=0, + options=None, + type=None), + descriptor.EnumValueDescriptor( + name='BUTTCAP', index=1, number=1, + options=None, + type=None), + descriptor.EnumValueDescriptor( + name='SQUARECAP', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=1469, + serialized_end=1520, ) @@ -73,59 +72,58 @@ BUTTCAP = 1 SQUARECAP = 2 - _DASHDOTPROTO = descriptor.Descriptor( - name='DashDotProto', - full_name='DashDotProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - descriptor.FieldDescriptor( - name='dd', full_name='DashDotProto.dd', index=0, - number=1, type=1, cpp_type=5, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - descriptor.FieldDescriptor( - name='offset', full_name='DashDotProto.offset', index=1, - number=2, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - serialized_start=23, - serialized_end=65, + name='DashDotProto', + full_name='DashDotProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + descriptor.FieldDescriptor( + name='dd', full_name='DashDotProto.dd', index=0, + number=1, type=1, cpp_type=5, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + descriptor.FieldDescriptor( + name='offset', full_name='DashDotProto.offset', index=1, + number=2, type=1, cpp_type=5, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=23, + serialized_end=65, ) _PATHSYMPROTO = descriptor.Descriptor( - name='PathSymProto', - full_name='PathSymProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - descriptor.FieldDescriptor( - name='name', full_name='PathSymProto.name', index=0, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - descriptor.FieldDescriptor( - name='step', full_name='PathSymProto.step', index=1, - number=2, type=1, cpp_type=5, label=2, + name='PathSymProto', + full_name='PathSymProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + descriptor.FieldDescriptor( + name='name', full_name='PathSymProto.name', index=0, + number=1, type=9, cpp_type=9, label=2, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + descriptor.FieldDescriptor( + name='step', full_name='PathSymProto.step', index=1, + number=2, type=1, cpp_type=5, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -725,82 +723,95 @@ DESCRIPTOR.message_types_by_name['DrawElementProto'] = _DRAWELEMENTPROTO DESCRIPTOR.message_types_by_name['ClassifElementProto'] = _CLASSIFELEMENTPROTO DESCRIPTOR.message_types_by_name['ContainerProto'] = _CONTAINERPROTO + class DashDotProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _DASHDOTPROTO - - # @@protoc_insertion_point(class_scope:DashDotProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _DASHDOTPROTO + + # @@protoc_insertion_point(class_scope:DashDotProto) + class PathSymProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _PATHSYMPROTO - - # @@protoc_insertion_point(class_scope:PathSymProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _PATHSYMPROTO + + # @@protoc_insertion_point(class_scope:PathSymProto) + class LineRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _LINERULEPROTO - - # @@protoc_insertion_point(class_scope:LineRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _LINERULEPROTO + + # @@protoc_insertion_point(class_scope:LineRuleProto) + class LineDefProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _LINEDEFPROTO - - # @@protoc_insertion_point(class_scope:LineDefProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _LINEDEFPROTO + + # @@protoc_insertion_point(class_scope:LineDefProto) + class AreaRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _AREARULEPROTO - - # @@protoc_insertion_point(class_scope:AreaRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _AREARULEPROTO + + # @@protoc_insertion_point(class_scope:AreaRuleProto) + class SymbolRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _SYMBOLRULEPROTO - - # @@protoc_insertion_point(class_scope:SymbolRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _SYMBOLRULEPROTO + + # @@protoc_insertion_point(class_scope:SymbolRuleProto) + class CaptionDefProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CAPTIONDEFPROTO - - # @@protoc_insertion_point(class_scope:CaptionDefProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _CAPTIONDEFPROTO + + # @@protoc_insertion_point(class_scope:CaptionDefProto) + class CaptionRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CAPTIONRULEPROTO - - # @@protoc_insertion_point(class_scope:CaptionRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _CAPTIONRULEPROTO + + # @@protoc_insertion_point(class_scope:CaptionRuleProto) + class CircleRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CIRCLERULEPROTO - - # @@protoc_insertion_point(class_scope:CircleRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _CIRCLERULEPROTO + + # @@protoc_insertion_point(class_scope:CircleRuleProto) + class PathTextRuleProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _PATHTEXTRULEPROTO - - # @@protoc_insertion_point(class_scope:PathTextRuleProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _PATHTEXTRULEPROTO + + # @@protoc_insertion_point(class_scope:PathTextRuleProto) + class DrawElementProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _DRAWELEMENTPROTO - - # @@protoc_insertion_point(class_scope:DrawElementProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _DRAWELEMENTPROTO + + # @@protoc_insertion_point(class_scope:DrawElementProto) + class ClassifElementProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CLASSIFELEMENTPROTO - - # @@protoc_insertion_point(class_scope:ClassifElementProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _CLASSIFELEMENTPROTO + + # @@protoc_insertion_point(class_scope:ClassifElementProto) + class ContainerProto(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CONTAINERPROTO - - # @@protoc_insertion_point(class_scope:ContainerProto) + __metaclass__ = reflection.GeneratedProtocolMessageType + DESCRIPTOR = _CONTAINERPROTO + + # @@protoc_insertion_point(class_scope:ContainerProto) # @@protoc_insertion_point(module_scope) diff --git a/src/generate_image.py b/src/generate_image.py index b22f52d..fbf2693 100644 --- a/src/generate_image.py +++ b/src/generate_image.py @@ -18,8 +18,8 @@ from debug import debug, Timer from backend.vtile import QuadTileBackend as DataBackend -#from backend.postgis import PostGisBackend as DataBackend -#from style import Styling +# from backend.postgis import PostGisBackend as DataBackend +# from style import Styling from mapcss import MapCSS from render import RasterTile @@ -30,22 +30,22 @@ if svg: import cairo -style = MapCSS(1, 19) #zoom levels -style.parse(open("styles/default.mapcss","r").read()) +style = MapCSS(1, 19) # zoom levels +style.parse(open("styles/default.mapcss", "r").read()) -bbox = (27.115768874532,53.740327031764,28.028320754378,54.067187302158) +bbox = (27.115768874532, 53.740327031764, 28.028320754378, 54.067187302158) -w,h = 630*4,364*4 +w, h = 630 * 4, 364 * 4 z = 10 db = DataBackend() -#style = Styling() +# style = Styling() res = RasterTile(w, h, z, db) if svg: file = open("test.svg", "wb") - res.surface = cairo.SVGSurface(file.name, w,h) + res.surface = cairo.SVGSurface(file.name, w, h) res.update_surface(bbox, z, style) diff --git a/src/generate_map_key.py b/src/generate_map_key.py index 0054f40..feaae07 100644 --- a/src/generate_map_key.py +++ b/src/generate_map_key.py @@ -19,88 +19,87 @@ maxzoom = 18 sample_width = 80 style = MapCSS(minzoom, maxzoom) -style.parse(open(sys.argv[1],"r").read(), clamp=False) +style.parse(open(sys.argv[1], "r").read(), clamp=False) tags = [json.loads(x) for x in open("data/tags.list", "r")] print len(tags) -#a = cairo.PDFSurface("legend.pdf",100,100*len(tags)) +# a = cairo.PDFSurface("legend.pdf",100,100*len(tags)) maxzoom += 1 -a = cairo.ImageSurface (cairo.FORMAT_ARGB32, maxzoom*sample_width, 50*len(tags)) +a = cairo.ImageSurface(cairo.FORMAT_ARGB32, maxzoom * sample_width, 50 * len(tags)) cr = cairo.Context(a) -cr.translate(0,0.5) +cr.translate(0, 0.5) i = 0 icons = {} for tag in tags: - had_lines = False - for zoom in range (minzoom, maxzoom): - styles = style.get_style_dict("node", tag, zoom, olddict = {}) - styles = style.get_style_dict("area", tag, zoom, olddict = styles.copy()) - styles = style.get_style_dict("line", tag, zoom, olddict = styles.copy()) - - styles = styles.values() - styles.sort(key=lambda x: x.get('z-index',0)) - if len(styles) > 0: - for st in styles: - if "fill-color" in st and st.get("fill-opacity", 1) > 0: - color = st.get('fill-color', (0.,0.,0.)) - cr.set_source_rgba(color[0], color[1], color[2], st.get("fill-opacity", 1)) - cr.move_to(0+sample_width*zoom, 20+50*i) - cr.line_to(sample_width+sample_width*zoom, 20+50*i) - cr.line_to(sample_width+sample_width*zoom, 55+50*i) - cr.line_to(0+sample_width*zoom, 20+50*i) - had_lines = True - cr.fill() - for st in styles: - if "casing-width" in st and st.get("casing-opacity", 1) > 0: - color = st.get('casing-color', (0.,0.,0.)) - cr.set_source_rgba(color[0], color[1], color[2], st.get("casing-opacity", 1)) - cr.set_line_width (st.get("width",0)+2*st.get("casing-width", 0)) - cr.set_dash(st.get('casing-dashes', st.get('dashes', []) )) - cr.move_to(0+sample_width*zoom, 50+50*i) - cr.line_to(sample_width+sample_width*zoom, 50+50*i) - had_lines = True - cr.stroke() - for st in styles: - if "width" in st and st.get("opacity", 1) > 0: - color = st.get('color', (0.,0.,0.)) - cr.set_source_rgba(color[0], color[1], color[2], st.get("opacity", 1)) - cr.set_line_width (st.get("width",0)) - cr.set_dash(st.get('dashes', [])) - cr.move_to(0+sample_width*zoom, 50+50*i) - cr.line_to(sample_width+sample_width*zoom, 50+50*i) - had_lines = True - cr.stroke() - if "icon-image" in st: - icons[st["icon-image"]] = icons.get(st["icon-image"], set()) - icons[st["icon-image"]].add('[' + ']['.join([ k+"="+v for k,v in tag.iteritems()])+']') - + had_lines = False + for zoom in range(minzoom, maxzoom): + styles = style.get_style_dict("node", tag, zoom, olddict={}) + styles = style.get_style_dict("area", tag, zoom, olddict=styles.copy()) + styles = style.get_style_dict("line", tag, zoom, olddict=styles.copy()) - if had_lines: - cr.move_to(0+sample_width*zoom, 25+50*i) - cr.set_source_rgb(0, 0, 0) - cr.show_text('z'+str(zoom)) + styles = styles.values() + styles.sort(key=lambda x: x.get('z-index', 0)) + if len(styles) > 0: + for st in styles: + if "fill-color" in st and st.get("fill-opacity", 1) > 0: + color = st.get('fill-color', (0., 0., 0.)) + cr.set_source_rgba(color[0], color[1], color[2], st.get("fill-opacity", 1)) + cr.move_to(0 + sample_width * zoom, 20 + 50 * i) + cr.line_to(sample_width + sample_width * zoom, 20 + 50 * i) + cr.line_to(sample_width + sample_width * zoom, 55 + 50 * i) + cr.line_to(0 + sample_width * zoom, 20 + 50 * i) + had_lines = True + cr.fill() + for st in styles: + if "casing-width" in st and st.get("casing-opacity", 1) > 0: + color = st.get('casing-color', (0., 0., 0.)) + cr.set_source_rgba(color[0], color[1], color[2], st.get("casing-opacity", 1)) + cr.set_line_width(st.get("width", 0) + 2 * st.get("casing-width", 0)) + cr.set_dash(st.get('casing-dashes', st.get('dashes', []))) + cr.move_to(0 + sample_width * zoom, 50 + 50 * i) + cr.line_to(sample_width + sample_width * zoom, 50 + 50 * i) + had_lines = True + cr.stroke() + for st in styles: + if "width" in st and st.get("opacity", 1) > 0: + color = st.get('color', (0., 0., 0.)) + cr.set_source_rgba(color[0], color[1], color[2], st.get("opacity", 1)) + cr.set_line_width(st.get("width", 0)) + cr.set_dash(st.get('dashes', [])) + cr.move_to(0 + sample_width * zoom, 50 + 50 * i) + cr.line_to(sample_width + sample_width * zoom, 50 + 50 * i) + had_lines = True + cr.stroke() + if "icon-image" in st: + icons[st["icon-image"]] = icons.get(st["icon-image"], set()) + icons[st["icon-image"]].add('[' + ']['.join([k + "=" + v for k, v in tag.iteritems()]) + ']') - if had_lines: - text = '[' + ']['.join([ k+"="+v for k,v in tag.iteritems()])+']' - cr.move_to(10, 20+50*i) + if had_lines: + cr.move_to(0 + sample_width * zoom, 25 + 50 * i) + cr.set_source_rgb(0, 0, 0) + cr.show_text('z' + str(zoom)) + + if had_lines: + text = '[' + ']['.join([k + "=" + v for k, v in tag.iteritems()]) + ']' + cr.move_to(10, 20 + 50 * i) cr.set_source_rgb(0, 0, 0) cr.show_text(text) - cr.set_line_width (1) + cr.set_line_width(1) cr.set_dash([]) - cr.move_to(0, 60+50*i) - cr.line_to(maxzoom*sample_width, 60+50*i) - + cr.move_to(0, 60 + 50 * i) + cr.line_to(maxzoom * sample_width, 60 + 50 * i) + cr.stroke() i += 1 -#a.finish()\ -ss = open("icons.html","w") +# a.finish()\ +ss = open("icons.html", "w") print >> ss, "" for k, v in icons.iteritems(): - print >> ss, "\n"%(k.lower(), k.lower(), "
".join(list(v))) + print >> ss, "\n" % (k.lower(), k.lower(), "
".join(list(v))) print >> ss, "
%s%s
%s%s
" -a.write_to_png ("legend.png") \ No newline at end of file +a.write_to_png("legend.png") diff --git a/src/gtk-app.py b/src/gtk-app.py index 3d3c131..aaa44fb 100644 --- a/src/gtk-app.py +++ b/src/gtk-app.py @@ -26,14 +26,12 @@ import Queue import os - -#from backend.postgis import PostGisBackend as DataBackend +# from backend.postgis import PostGisBackend as DataBackend from backend.vtile import QuadTileBackend as DataBackend from mapcss import MapCSS as Styling from gtk_widget import KothicWidget - try: import psyco psyco.full() @@ -52,12 +50,9 @@ class KothicApp: self.data = DataBackend() self.load_style() - - self.request_d = (0,0) + self.request_d = (0, 0) self.window = gtk.Window() - - self.window.set_size_request(self.width, self.height) self.window.connect("destroy", gtk.main_quit) @@ -75,7 +70,7 @@ class KothicApp: stylemenu = gtk.Menu() stylem = gtk.MenuItem("Style") stylem.set_submenu(stylemenu) - styles = [name for name in os.listdir("styles") if ".mapcss" in name] + styles = [name for name in os.listdir("styles") if ".mapcss" in name] for style in styles: i = gtk.MenuItem(style) i.StyleName = style @@ -90,29 +85,26 @@ class KothicApp: menu.append(stylem) vbox = gtk.VBox(False, 2) - vbox.pack_start(menu,False,False,0) + vbox.pack_start(menu, False, False, 0) self.KothicWidget = KothicWidget(self.data, self.style) self.KothicWidget.set_zoom(self.zoom) self.KothicWidget.jump_to(self.center_coord) - - vbox.pack_end(self.KothicWidget) - self.window.add(vbox) def load_style(self): - self.style = Styling(0,25) - self.style.parse(open("styles/osmosnimki-maps.mapcss","r").read()) - def reload_style(self,w): - self.style = Styling(0,25) - self.style.parse(open("styles/%s"%w.StyleName,"r").read()) + self.style = Styling(0, 25) + self.style.parse(open("styles/osmosnimki-maps.mapcss", "r").read()) + + def reload_style(self, w): + self.style = Styling(0, 25) + self.style.parse(open("styles/%s" % w.StyleName, "r").read()) self.KothicWidget.style_backend = self.style self.KothicWidget.redraw() - def main(self): self.window.show_all() diff --git a/src/gtk_widget.py b/src/gtk_widget.py index 14d134e..263dea8 100644 --- a/src/gtk_widget.py +++ b/src/gtk_widget.py @@ -31,13 +31,14 @@ from debug import debug, Timer import twms.bbox from twms import projections + class KothicWidget(gtk.DrawingArea): def __init__(self, data, style): gtk.DrawingArea.__init__(self) self.data_backend = data self.style_backend = style - self.request_d = (0,0) - self.tiles = TileSource(data,style, callback=self.redraw) + self.request_d = (0, 0) + self.tiles = TileSource(data, style, callback=self.redraw) self.dx = 0 self.dy = 0 self.drag_x = 0 @@ -50,145 +51,146 @@ class KothicWidget(gtk.DrawingArea): self.max_zoom = 25 self.zoom = 0 - self.center_coord = (0.0,0.0) + self.center_coord = (0.0, 0.0) self.old_zoom = 1 - self.old_center_coord = (0.0,0.1) + self.old_center_coord = (0.0, 0.1) self.tilebox = [] # bbox of currently seen tiles self.bbox = [] - self.add_events(gtk.gdk.BUTTON1_MOTION_MASK) self.add_events(gtk.gdk.POINTER_MOTION_MASK) self.add_events(gtk.gdk.BUTTON_PRESS_MASK) self.add_events(gtk.gdk.BUTTON_RELEASE_MASK) self.add_events(gtk.gdk.SCROLL) # self.window.add_events(gtk.gdk.BUTTON1_MOTION_MASK) - self.connect("expose_event",self.expose_ev) - self.connect("motion_notify_event",self.motion_ev) - self.connect("button_press_event",self.press_ev) - self.connect("button_release_event",self.release_ev) - self.connect("scroll_event",self.scroll_ev) + self.connect("expose_event", self.expose_ev) + self.connect("motion_notify_event", self.motion_ev) + self.connect("button_press_event", self.press_ev) + self.connect("button_release_event", self.release_ev) + self.connect("scroll_event", self.scroll_ev) # self.surface = cairo.ImageSurfaceicreate(gtk.RGB24, self.width, self.height) - def set_zoom(self, zoom): self.zoom = zoom self.queue_draw() + def jump_to(self, lonlat): self.center_coord = lonlat self.queue_draw() + def zoom_to(self, bbox): - self.zoom = twms.bbox.zoom_for_bbox (bbox, (self.width,self.height), {"proj":"EPSG:3857","max_zoom":self.max_zoom})-1 + self.zoom = twms.bbox.zoom_for_bbox(bbox, (self.width, self.height), {"proj": "EPSG:3857", "max_zoom": self.max_zoom}) - 1 print "Zoom:", self.zoom - self.center_coord = ((bbox[0]+bbox[2])/2,(bbox[1]+bbox[3])/2) + self.center_coord = ((bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2) print self.center_coord self.redraw() - def motion_ev(self, widget, event): if self.drag: self.dx = event.x - self.drag_x self.dy = event.y - self.drag_y - #if((abs(self.dx) > 3 or abs(self.dy) > 3) and self.f): + # if((abs(self.dx) > 3 or abs(self.dy) > 3) and self.f): if True: # x = event.x # y = event.y # lo1, la1, lo2, la2 = self.tilebox # self.center_coord = projections.coords_by_tile(self.zoom,1.*x/self.width*(lo2-lo1)+lo1, la1+(1.*y/(self.height)*(la2-la1)),"EPSG:3857") widget.queue_draw() + def press_ev(self, widget, event): if event.button == 1: - #debug("Start drag") + # debug("Start drag") self.drag = True self.drag_x = event.x self.drag_y = event.y self.timer = Timer("Drag") - #elif event.button == 2: - #debug("Button2") - #elif event.button == 3: - #debug("Button3") + # elif event.button == 2: + # debug("Button2") + # elif event.button == 3: + # debug("Button3") + def release_ev(self, widget, event): if event.button == 1: - #debug("Stop drag") + # debug("Stop drag") self.drag = False self.timer.stop() - #debug("dd: %s,%s "%(self.dx, self.dy)) + # debug("dd: %s,%s "%(self.dx, self.dy)) x = event.x y = event.y lo1, la1, lo2, la2 = projections.from4326(self.bbox, "EPSG:3857") print lo1, la1, lo2, la2 - #self.center_coord = projections.to4326((0.5*(self.width+self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+self.dy)/self.height*(la2-la1))),"EPSG:3857") + # self.center_coord = projections.to4326((0.5*(self.width+self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+self.dy)/self.height*(la2-la1))),"EPSG:3857") - self.center_coord = projections.to4326((0.5*(self.width+2*self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+2*self.dy)/self.height*(la2-la1))),"EPSG:3857") - #self.rastertile.screen2lonlat(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy); + self.center_coord = projections.to4326((0.5 * (self.width + 2 * self.dx) / self.width * (lo1 - lo2) + lo2, la1 + (0.5 * (self.height + 2 * self.dy) / self.height * (la2 - la1))), "EPSG:3857") + # self.rastertile.screen2lonlat(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy); self.dx = 0 self.dy = 0 self.redraw() def scroll_ev(self, widget, event): if event.direction == gtk.gdk.SCROLL_UP: - if self.zoom+0.5 <= self.max_zoom: + if self.zoom + 0.5 <= self.max_zoom: self.zoom += 0.5 - #debug("Zoom in") + # debug("Zoom in") elif event.direction == gtk.gdk.SCROLL_DOWN: - if self.zoom >= 0: ## negative zooms are nonsense + if self.zoom >= 0: # negative zooms are nonsense self.zoom -= 0.5 # debug("Zoom out") - #self.redraw() - debug("new zoom: %s"%(self.zoom)) + # self.redraw() + debug("new zoom: %s" % (self.zoom)) widget.queue_draw() + def redraw(self): """ Force screen redraw. """ - #res = RasterTile(3*self.width, 3*self.height, self.zoom, self.data_backend) - #res.update_surface_by_center(self.center_coord, self.zoom, self.style_backend) - #self.rastertile = res + # res = RasterTile(3*self.width, 3*self.height, self.zoom, self.data_backend) + # res.update_surface_by_center(self.center_coord, self.zoom, self.style_backend) + # self.rastertile = res self.queue_draw() - def expose_ev(self, widget, event): - if(widget.allocation.width != self.width or widget.allocation.height != self.height ): - #debug("Rrresize!") + if(widget.allocation.width != self.width or widget.allocation.height != self.height): + # debug("Rrresize!") self.width = widget.allocation.width self.height = widget.allocation.height cr = widget.window.cairo_create() if self.old_center_coord != self.center_coord or self.old_zoom != self.zoom: - #print "Recentered!" - xy = projections.from4326(self.center_coord,"EPSG:3857") - xy1 = projections.to4326((xy[0]-40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]-40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857") - xy2 = projections.to4326((xy[0]+40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]+40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857") - self.bbox = (xy1[0],xy1[1],xy2[0],xy2[1]) + # print "Recentered!" + xy = projections.from4326(self.center_coord, "EPSG:3857") + xy1 = projections.to4326((xy[0] - 40075016. * (0.5 ** (self.zoom)) / self.tiles.tilewidth * self.width, xy[1] - 40075016. * (0.5 ** (self.zoom)) / self.tiles.tileheight * self.height), "EPSG:3857") + xy2 = projections.to4326((xy[0] + 40075016. * (0.5 ** (self.zoom)) / self.tiles.tilewidth * self.width, xy[1] + 40075016. * (0.5 ** (self.zoom)) / self.tiles.tileheight * self.height), "EPSG:3857") + self.bbox = (xy1[0], xy1[1], xy2[0], xy2[1]) self.tilebox = projections.tile_by_bbox(self.bbox, self.zoom, "EPSG:3857") self.old_center_coord = self.center_coord self.old_zoom = self.zoom from_tile_x, from_tile_y, to_tile_x, to_tile_y = self.tilebox - dx = 1.*(from_tile_x - int(from_tile_x))*self.tiles.tilewidth - dy = 1.*(from_tile_y - int(from_tile_y))*self.tiles.tileheight - print dx,dy - #print self.dx, self.dy + dx = 1. * (from_tile_x - int(from_tile_x)) * self.tiles.tilewidth + dy = 1. * (from_tile_y - int(from_tile_y)) * self.tiles.tileheight + print dx, dy + # print self.dx, self.dy onscreen_tiles = set() - for x in range (int(from_tile_x), int(to_tile_x)+1): - for y in range (int(to_tile_y), int(from_tile_y)+1): - onscreen_tiles.add((self.zoom,x,y)) + for x in range(int(from_tile_x), int(to_tile_x) + 1): + for y in range(int(to_tile_y), int(from_tile_y) + 1): + onscreen_tiles.add((self.zoom, x, y)) self.tiles.onscreen = onscreen_tiles - for z,x,y in onscreen_tiles: - tile = self.tiles[(self.zoom,x,y)] - #print dx+(x-from_tile_x)*self.tiles.tilewidth-self.width - #print dy+(y-from_tile_y)*self.tiles.tileheight-self.height - #cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth-self.width), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height)) - cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height)) + for z, x, y in onscreen_tiles: + tile = self.tiles[(self.zoom, x, y)] + # print dx+(x-from_tile_x)*self.tiles.tilewidth-self.width + # print dy+(y-from_tile_y)*self.tiles.tileheight-self.height + # cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth-self.width), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height)) + cr.set_source_surface(tile, int(self.dx - dx + (x - int(from_tile_x)) * self.tiles.tilewidth), int(self.dy - dy - (int(from_tile_y) - y) * self.tiles.tileheight + self.height)) cr.paint() - #cr.set_source_surface(self.rastertile.surface, self.dx-self.width + self.rastertile.offset_x, self.dy - self.height + self.rastertile.offset_y) + # cr.set_source_surface(self.rastertile.surface, self.dx-self.width + self.rastertile.offset_x, self.dy - self.height + self.rastertile.offset_y) - #self.comm[3].release() + # self.comm[3].release() class TileSource: - def __init__(self,data,style, callback = lambda: None): + def __init__(self, data, style, callback=lambda: None): self.tiles = {} self.tilewidth = 2048 self.tileheight = 2048 @@ -199,79 +201,82 @@ class TileSource: self.onscreen = set() self._singlethread = False self._prerender = True - def __getitem__(self,(z,x,y),wait=False): + + def __getitem__(self, (z, x, y), wait=False): try: - #if "surface" in self.tiles[(z,x,y)] and not wait: + # if "surface" in self.tiles[(z,x,y)] and not wait: # self._callback((z,x,y), True) print "Tiles count:", len(self.tiles) - return self.tiles[(z,x,y)]["surface"] + return self.tiles[(z, x, y)]["surface"] except: - self.tiles[(z,x,y)] = {"tile": RasterTile(self.tilewidth, self.tileheight, z, self.data_backend)} - self.tiles[(z,x,y)]["start_time"] = datetime.datetime.now() + self.tiles[(z, x, y)] = {"tile": RasterTile(self.tilewidth, self.tileheight, z, self.data_backend)} + self.tiles[(z, x, y)]["start_time"] = datetime.datetime.now() if self._singlethread: - self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface - self.tiles[(z,x,y)]["tile"].update_surface(projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p)) + self.tiles[(z, x, y)]["surface"] = self.tiles[(z, x, y)]["tile"].surface + self.tiles[(z, x, y)]["tile"].update_surface(projections.bbox_by_tile(z, x, y, "EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z, x, y), p)) - del self.tiles[(z,x,y)]["tile"] + del self.tiles[(z, x, y)]["tile"] else: - self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface.create_similar(cairo.CONTENT_COLOR_ALPHA, self.tilewidth, self.tileheight) - self.tiles[(z,x,y)]["thread"] = threading.Thread(None, self.tiles[(z,x,y)]["tile"].update_surface,None, (projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p))) - self.tiles[(z,x,y)]["thread"].start() + self.tiles[(z, x, y)]["surface"] = self.tiles[(z, x, y)]["tile"].surface.create_similar(cairo.CONTENT_COLOR_ALPHA, self.tilewidth, self.tileheight) + self.tiles[(z, x, y)]["thread"] = threading.Thread(None, self.tiles[(z, x, y)]["tile"].update_surface, None, (projections.bbox_by_tile(z, x, y, "EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z, x, y), p))) + self.tiles[(z, x, y)]["thread"].start() if wait: - self.tiles[(z,x,y)]["thread"].join() - return self.tiles[(z,x,y)]["surface"] - def _callback (self, (z,x,y),last): - #if last: + self.tiles[(z, x, y)]["thread"].join() + return self.tiles[(z, x, y)]["surface"] + + def _callback(self, (z, x, y), last): + # if last: # print last, "dddddddddddddddddd" if not self._singlethread: - if ((z,x,y) in self.onscreen or last) and "tile" in self.tiles[(z,x,y)]: - cr = cairo.Context(self.tiles[(z,x,y)]["surface"]) - cr.set_source_surface(self.tiles[(z,x,y)]["tile"].surface,0,0) + if ((z, x, y) in self.onscreen or last) and "tile" in self.tiles[(z, x, y)]: + cr = cairo.Context(self.tiles[(z, x, y)]["surface"]) + cr.set_source_surface(self.tiles[(z, x, y)]["tile"].surface, 0, 0) cr.paint() if last: try: - del self.tiles[(z,x,y)]["thread"] - del self.tiles[(z,x,y)]["tile"] + del self.tiles[(z, x, y)]["thread"] + del self.tiles[(z, x, y)]["tile"] except KeyError: pass - self.tiles[(z,x,y)]["finish_time"] = datetime.datetime.now() - self.tiles[(z,x,y)]["start_time"] + self.tiles[(z, x, y)]["finish_time"] = datetime.datetime.now() - self.tiles[(z, x, y)]["start_time"] gobject.idle_add(self.callback) self.collect_grabage() if last and self._prerender: - if (z,x,y) in self.onscreen: - a = self.__getitem__((z-1,x/2,y/2),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z+1,x*2,y*2),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z+1,x*2+1,y*2),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z+1,x*2,y*2+1),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z+1,x*2+1,y*2+1),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z,x+1,y),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z,x,y+1),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z,x-1,y),True) - if (z,x,y) in self.onscreen: - a = self.__getitem__((z,x,y-1),True) - def collect_grabage (self): - if len(self.tiles)> self.max_tiles: + if (z, x, y) in self.onscreen: + a = self.__getitem__((z - 1, x / 2, y / 2), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z + 1, x * 2, y * 2), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z + 1, x * 2 + 1, y * 2), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z + 1, x * 2, y * 2 + 1), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z + 1, x * 2 + 1, y * 2 + 1), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z, x + 1, y), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z, x, y + 1), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z, x - 1, y), True) + if (z, x, y) in self.onscreen: + a = self.__getitem__((z, x, y - 1), True) + + def collect_grabage(self): + if len(self.tiles) > self.max_tiles: # let's kick out the fastest rendered tiles - it's easy to rerender those # don't touch onscreen tiles cand = set(self.tiles.keys()) cand.difference_update(self.onscreen) cand = [i for i in cand if "finish_time" in self.tiles[i]] - cand.sort(lambda i,j: self.tiles[i]["finish_time"] self.max_tiles): + if (len(self.tiles) > self.max_tiles): c = cand.pop() try: - print "Killed tile ", c, " - finished in ",str(self.tiles[c]["finish_time"]), ", ago:", str(datetime.datetime.now()-self.tiles[c]["start_time"]) + print "Killed tile ", c, " - finished in ", str(self.tiles[c]["finish_time"]), ", ago:", str(datetime.datetime.now() - self.tiles[c]["start_time"]) del self.tiles[c] except KeyError: pass @@ -279,7 +284,6 @@ class TileSource: break - if __name__ == "__main__": gtk.gdk.threads_init() diff --git a/src/json_getter.py b/src/json_getter.py index 40f5c59..684f03c 100644 --- a/src/json_getter.py +++ b/src/json_getter.py @@ -15,9 +15,10 @@ try: psyco.full() except ImportError: pass - #print >>sys.stderr, "Psyco import failed. Program may run slower. If you run it on i386 machine, please install Psyco to get best performance." + # print >>sys.stderr, "Psyco import failed. Program may run slower. If you run it on i386 machine, please install Psyco to get best performance." -def get_vectors(bbox, zoom, style, vec = "polygon"): + +def get_vectors(bbox, zoom, style, vec="polygon"): bbox_p = projections.from4326(bbox, "EPSG:3857") geomcolumn = "way" @@ -25,7 +26,7 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): pxtolerance = 1.8 intscalefactor = 10000 ignore_columns = set(["way_area", "osm_id", geomcolumn, "tags", "z_order"]) - table = {"polygon":"planet_osm_polygon", "line":"planet_osm_line","point":"planet_osm_point", "coastline": "coastlines"} + table = {"polygon": "planet_osm_polygon", "line": "planet_osm_line", "point": "planet_osm_point", "coastline": "coastlines"} a = psycopg2.connect(database) b = a.cursor() @@ -35,11 +36,10 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): for i in ignore_columns: if i in names: names.remove(i) - names = ",".join(['"'+i+'"' for i in names]) - + names = ",".join(['"' + i + '"' for i in names]) taghint = "*" - types = {"line":"line","polygon":"area", "point":"node"} + types = {"line": "line", "polygon": "area", "point": "node"} adp = "" if "get_sql_hints" in dir(style): sql_hint = style.get_sql_hints(types[vec], zoom) @@ -53,14 +53,13 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): add.append(tp[1]) if add: add = " OR ".join(add) - add = "("+add+")" + add = "(" + add + ")" adp.append(add) adp = " OR ".join(adp) if adp: adp = adp.replace("<", "<") adp = adp.replace(">", ">") - if vec == "polygon": query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s, ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_PointOnSurface(way)),%s,%s,%s,%s),0) as reprpoint, %s from @@ -77,23 +76,23 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): where ST_Area(way) > %s order by ST_Area(way) ) p - """%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], - -bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]), - geomcolumn, - -bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]), - names, - pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance), - geomcolumn, names, - geomcolumn, names, - pixel_size_at_zoom(zoom, pxtolerance), - geomcolumn, names, - table[vec], - adp, - bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], - (pixel_size_at_zoom(zoom, pxtolerance)**2)/pxtolerance, - names, - pixel_size_at_zoom(zoom, pxtolerance)**2 - ) + """ % (bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], + -bbox_p[0], -bbox_p[1], intscalefactor / (bbox_p[2] - bbox_p[0]), intscalefactor / (bbox_p[3] - bbox_p[1]), + geomcolumn, + -bbox_p[0], -bbox_p[1], intscalefactor / (bbox_p[2] - bbox_p[0]), intscalefactor / (bbox_p[3] - bbox_p[1]), + names, + pixel_size_at_zoom(zoom, pxtolerance), pixel_size_at_zoom(zoom, pxtolerance), + geomcolumn, names, + geomcolumn, names, + pixel_size_at_zoom(zoom, pxtolerance), + geomcolumn, names, + table[vec], + adp, + bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], + (pixel_size_at_zoom(zoom, pxtolerance) ** 2) / pxtolerance, + names, + pixel_size_at_zoom(zoom, pxtolerance) ** 2 + ) elif vec == "line": query = """select ST_AsGeoJSON(ST_TransScale(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)),%s,%s,%s,%s),0) as %s, %s from (select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_LineMerge(way),%s)))).geom as %s, %s from @@ -106,33 +105,33 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): ) p ) p - """%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], - -bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]), - geomcolumn, names, - pixel_size_at_zoom(zoom, pxtolerance), - geomcolumn, names, - geomcolumn, names, - table[vec], - adp, - bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], + """ % (bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], + -bbox_p[0], -bbox_p[1], intscalefactor / (bbox_p[2] - bbox_p[0]), intscalefactor / (bbox_p[3] - bbox_p[1]), + geomcolumn, names, + pixel_size_at_zoom(zoom, pxtolerance), + geomcolumn, names, + geomcolumn, names, + table[vec], + adp, + bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], - names, + names, - ) + ) elif vec == "point": query = """select ST_AsGeoJSON(ST_TransScale(way,%s,%s,%s,%s),0) as %s, %s from %s where (%s) and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913) limit 10000 - """%( - -bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]), - geomcolumn, names, - table[vec], - adp, - bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], + """ % ( + -bbox_p[0], -bbox_p[1], intscalefactor / (bbox_p[2] - bbox_p[0]), intscalefactor / (bbox_p[3] - bbox_p[1]), + geomcolumn, names, + table[vec], + adp, + bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], - ) + ) elif vec == "coastline": query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s, 'coastline' as "natural" from (select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_Buffer(way,-%s),%s)))).geom as %s from @@ -145,19 +144,19 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): ) p where ST_Area(way) > %s ) p - """%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], - -bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]), - geomcolumn, - pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance), - geomcolumn, - geomcolumn, - pixel_size_at_zoom(zoom, pxtolerance), - geomcolumn, - table[vec], - bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3], - pixel_size_at_zoom(zoom, pxtolerance)**2 - ) - #print query + """ % (bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], + -bbox_p[0], -bbox_p[1], intscalefactor / (bbox_p[2] - bbox_p[0]), intscalefactor / (bbox_p[3] - bbox_p[1]), + geomcolumn, + pixel_size_at_zoom(zoom, pxtolerance), pixel_size_at_zoom(zoom, pxtolerance), + geomcolumn, + geomcolumn, + pixel_size_at_zoom(zoom, pxtolerance), + geomcolumn, + table[vec], + bbox_p[0], bbox_p[1], bbox_p[2], bbox_p[3], + pixel_size_at_zoom(zoom, pxtolerance) ** 2 + ) + # print query a = psycopg2.connect(database) b = a.cursor() b.execute(query) @@ -168,7 +167,7 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): for row in b.fetchall(): ROWS_FETCHED += 1 - geom = dict(map(None,names,row)) + geom = dict(map(None, names, row)) for t in geom.keys(): if not geom[t]: del geom[t] @@ -180,7 +179,7 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): geojson["reprpoint"] = json.loads(geom["reprpoint"])["coordinates"] del geom["reprpoint"] prop = {} - for k,v in geom.iteritems(): + for k, v in geom.iteritems(): prop[k] = v try: if int(v) == float(v): @@ -193,9 +192,7 @@ def get_vectors(bbox, zoom, style, vec = "polygon"): pass geojson["properties"] = prop polygons.append(geojson) - return {"bbox": bbox, "granularity":intscalefactor, "features":polygons} - - + return {"bbox": bbox, "granularity": intscalefactor, "features": polygons} print "Content-Type: text/html" @@ -214,25 +211,25 @@ if "y" not in form: z = int(form["z"].value) x = int(form["x"].value) y = int(form["y"].value) -if z>22: +if z > 22: exit() callback = "onKothicDataResponse" -bbox = projections.bbox_by_tile(z+1,x,y,"EPSG:3857") +bbox = projections.bbox_by_tile(z + 1, x, y, "EPSG:3857") -style = MapCSS(0,30) -style.parse(open("styles/osmosnimki-maps.mapcss","r").read()) -zoom = z+2 -aaaa = get_vectors(bbox,zoom,style,"coastline") -aaaa["features"].extend(get_vectors(bbox,zoom,style,"polygon")["features"]) -aaaa["features"].extend(get_vectors(bbox,zoom,style,"line")["features"]) -aaaa["features"].extend(get_vectors(bbox,zoom,style,"point")["features"]) +style = MapCSS(0, 30) +style.parse(open("styles/osmosnimki-maps.mapcss", "r").read()) +zoom = z + 2 +aaaa = get_vectors(bbox, zoom, style, "coastline") +aaaa["features"].extend(get_vectors(bbox, zoom, style, "polygon")["features"]) +aaaa["features"].extend(get_vectors(bbox, zoom, style, "line")["features"]) +aaaa["features"].extend(get_vectors(bbox, zoom, style, "point")["features"]) -aaaa = callback+"("+json.dumps(aaaa,True,False,separators=(',', ':'))+",%s,%s,%s);"%(z,x,y) +aaaa = callback + "(" + json.dumps(aaaa, True, False, separators=(',', ':')) + ",%s,%s,%s);" % (z, x, y) print aaaa -dir = "/var/www/vtile/%s/%s/"%(z,x) -file = "%s.js"%y +dir = "/var/www/vtile/%s/%s/" % (z, x) +file = "%s.js" % y try: if not os.path.exists(dir): @@ -240,7 +237,7 @@ try: except: pass -file = open(dir+file,"w") +file = open(dir + file, "w") file.write(aaaa) file.flush() file.close() diff --git a/src/komap.py b/src/komap.py index 94f4fd2..07857dc 100755 --- a/src/komap.py +++ b/src/komap.py @@ -40,6 +40,7 @@ import math config = ConfigParser.ConfigParser() + def relaxedFloat(x): try: return float(x) if int(float(x)) != float(x) else int(x) @@ -49,45 +50,46 @@ def relaxedFloat(x): parser = OptionParser() parser.add_option("-r", "--renderer", dest="renderer", default="mapnik", - help="which renderer stylesheet to generate", metavar="ENGINE") + help="which renderer stylesheet to generate", metavar="ENGINE") parser.add_option("-s", "--stylesheet", dest="filename", - help="read MapCSS stylesheet from FILE", metavar="FILE") + 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") + 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") + help="maximal available zoom level", metavar="ZOOM") parser.add_option("-l", "--locale", dest="locale", - help="language that should be used for labels (ru, en, be, uk..)", metavar="LANG") + help="language that should be used for labels (ru, en, be, uk..)", metavar="LANG") parser.add_option("-o", "--output-file", dest="outfile", default="-", - help="output filename (defaults to stdout)", metavar="FILE") + help="output filename (defaults to stdout)", metavar="FILE") parser.add_option("-p", "--osm2pgsql-style", dest="osm2pgsqlstyle", default="-", - help="osm2pgsql stylesheet filename", metavar="FILE") + help="osm2pgsql stylesheet filename", metavar="FILE") parser.add_option("-b", "--background-only", dest="bgonly", action="store_true", default=False, - help="Skip rendering of icons and labels", metavar="BOOL") + help="Skip rendering of icons and labels", metavar="BOOL") parser.add_option("-T", "--text-scale", dest="textscale", default=1, type="float", - help="text size scale", metavar="SCALE") + help="text size scale", metavar="SCALE") parser.add_option("-c", "--config", dest="conffile", default="komap.conf", - help="config file name", metavar="FILE") + help="config file name", metavar="FILE") (options, args) = parser.parse_args() -if (options.filename == None): +if (options.filename is None): parser.error("MapCSS stylesheet filename is required") -def escape_sql_column(name, type="way", asname = False): - if name in mapped_cols: - return name # already escaped - name = name.strip().strip('"') - type = {'line':'way', 'area':'way'}.get(type,type) - if type in osm2pgsql_avail_keys.get(name, ()) or not osm2pgsql_avail_keys: - return '"'+name+'"' - elif not asname: - return "(tags->'"+name+"')" - else: - return "(tags->'"+name+"') as \"" +name+'"' -style = MapCSS(options.minzoom, options.maxzoom+1) #zoom levels -style.parse(open(options.filename,"r").read()) +def escape_sql_column(name, type="way", asname=False): + if name in mapped_cols: + return name # already escaped + name = name.strip().strip('"') + type = {'line': 'way', 'area': 'way'}.get(type, type) + if type in osm2pgsql_avail_keys.get(name, ()) or not osm2pgsql_avail_keys: + return '"' + name + '"' + elif not asname: + return "(tags->'" + name + "')" + else: + return "(tags->'" + name + "') as \"" + name + '"' + +style = MapCSS(options.minzoom, options.maxzoom + 1) # zoom levels +style.parse(open(options.filename, "r").read()) if options.renderer == "mapswithme": from libkomwm import * @@ -97,7 +99,7 @@ if options.renderer == "mapswithme": if options.outfile == "-": mfile = sys.stdout else: - mfile = open(options.outfile,"w") + mfile = open(options.outfile, "w") if options.renderer == "js": from libkojs import * @@ -121,19 +123,16 @@ if options.renderer == "mapnik": libkomapnik.srtm_hs_path = config.get("mapnik", "srtm_hs_path") libkomapnik.text_scale = options.textscale - from libkomapnik import * - - - osm2pgsql_avail_keys = {} # "column" : ["node", "way"] + osm2pgsql_avail_keys = {} # "column" : ["node", "way"] if options.osm2pgsqlstyle != "-": mf = open(options.osm2pgsqlstyle, "r") for line in mf: line = line.strip().split() if line and line[0][0] != "#" and not ("phstore" in line): osm2pgsql_avail_keys[line[1]] = tuple(line[0].split(",")) - osm2pgsql_avail_keys["tags"] = ("node","way") + osm2pgsql_avail_keys["tags"] = ("node", "way") columnmap = {} @@ -154,7 +153,7 @@ if options.renderer == "mapnik": 'lЁ', 'lIo'), 'lЮ', 'lIu'), 'lЯ', 'lIa'), 'lе', 'lie'), 'lё', 'lio'), 'lю', 'liu'), 'lя', 'lia'), 'mЕ', 'mIe'), 'mЁ', 'mIo'), 'mЮ', 'mIu'), 'mЯ', 'mIa'), 'mе', 'mie'), 'mё', 'mio'), 'mю', 'miu'), 'mя', 'mia'), 'nЕ', 'nIe'), 'nЁ', 'nIo'), 'nЮ', 'nIu'), 'nЯ', 'nIa'), 'nе', 'nie'), 'nё', 'nio'), 'nю', 'niu'), 'nя', 'nia'), 'pЕ', 'pIe'), 'pЁ', 'pIo'), 'pЮ', 'pIu'), 'pЯ', 'pIa'), 'pе', 'pie'), 'pё', 'pio'), 'pю', 'piu'), 'pя', 'pia'), 'rЕ', 'rIe'), 'rЁ', 'rIo'), 'rЮ', 'rIu'), 'rЯ', 'rIa'), 'rе', 'rie'), 'rё', 'rio'), 'rю', 'riu'), 'rя', 'ria'), 'sЕ', 'sIe'), 'sЁ', 'sIo'), 'sЮ', 'sIu'), 'sЯ', 'sIa'), 'sе', 'sie'), 'sё', 'sio'), 'sю', 'siu'), 'sя', 'sia'), 'tЕ', 'tIe'), 'tЁ', 'tIo'), 'tЮ', 'tIu'), 'tЯ', 'tIa'), 'tе', 'tie'), 'tё', 'tio'), 'tю', 'tiu'), 'tя', 'tia'), 'ŭЕ', 'ŭIe'), 'ŭЁ', 'ŭIo'), 'ŭЮ', 'ŭIu'), 'ŭЯ', 'ŭIa'), 'ŭе', 'ŭie'), 'ŭё', 'ŭio'), 'ŭю', 'ŭiu'), 'ŭя', 'ŭia'), 'fЕ', 'fIe'), 'fЁ', 'fIo'), 'fЮ', 'fIu'), 'fЯ', 'fIa'), 'fе', 'fie'), 'fё', 'fio'), 'fю', 'fiu'), 'fя', 'fia'), 'сЕ', 'сIe'), 'сЁ', 'сIo'), 'сЮ', 'сIu'), 'сЯ', 'сIa'), 'се', 'сie'), 'сё', 'сio'), 'сю', 'сiu'), 'ся', 'сia'), 'čЕ', 'čIe'), 'čЁ', 'čIo'), 'čЮ', 'čIu'), 'čЯ', 'čIa'), 'čе', 'čie'), 'čё', 'čio'), 'čю', 'čiu'), 'čя', 'čia'), 'šЕ', 'šIe'), 'šЁ', 'šIo'), 'šЮ', 'šIu'), 'šЯ', 'šIa'), 'šе', 'šie'), 'šё', 'šio'), 'šю', 'šiu'), 'šя', 'šia'), 'Е', 'Je'), 'Ё', 'Jo'), 'Ю', 'Ju'), 'Я', 'Ja'), 'е', 'je'), 'ё', 'jo'), 'ю', 'ju'), 'я', 'ja'), 'Ь', '\u0301'), 'ь', '\u0301'),'’', ''), - replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(translate("name",'абвгдезиклмнопрстуфьАБВГДЕЗИКЛМНОПРСТУФЬ','abvgdeziklmnoprstuf’ABVGDEZIKLMNOPRSTUF’'),'х','kh'),'Х','Kh'),'ц','ts'),'Ц','Ts'),'ч','ch'),'Ч','Ch'),'ш','sh'),'Ш','Sh'),'щ','shch'),'Щ','Shch'),'ъ','”'),'Ъ','”'),'ё','yo'),'Ё','Yo'),'ы','y'),'Ы','Y'),'э','·e'),'Э','E'),'ю','yu'),'Ю','Yu'),'й','y'),'Й','Y'),'я','ya'),'Я','Ya'),'ж','zh'),'Ж','Zh')) AS name""",('name:en','int_name','name:be')) + replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(translate("name",'абвгдезиклмнопрстуфьАБВГДЕЗИКЛМНОПРСТУФЬ','abvgdeziklmnoprstuf’ABVGDEZIKLMNOPRSTUF’'),'х','kh'),'Х','Kh'),'ц','ts'),'Ц','Ts'),'ч','ch'),'Ч','Ch'),'ш','sh'),'Ш','Sh'),'щ','shch'),'Щ','Shch'),'ъ','”'),'Ъ','”'),'ё','yo'),'Ё','Yo'),'ы','y'),'Ы','Y'),'э','·e'),'Э','E'),'ю','yu'),'Ю','Yu'),'й','y'),'Й','Y'),'я','ya'),'Я','Ya'),'ж','zh'),'Ж','Zh')) AS name""", ('name:en', 'int_name', 'name:be')) elif options.locale == "be": columnmap["name"] = ("""COALESCE("name:be", @@ -162,11 +161,11 @@ if options.renderer == "mapnik": "int_name", "name:en", "name" - ) AS name"""%(table_prefix,table_prefix,table_prefix),('name:be', "name:ru", "int_name", "name:en")) - elif options.locale and ("name:"+options.locale in osm2pgsql_avail_keys or not osm2pgsql_avail_keys): - columnmap["name"] = ('COALESCE("name:'+options.locale+'", "name") AS name',('name:'+options.locale,)) + ) AS name""" % (table_prefix, table_prefix, table_prefix), ('name:be', "name:ru", "int_name", "name:en")) + elif options.locale and ("name:" + options.locale in osm2pgsql_avail_keys or not osm2pgsql_avail_keys): + columnmap["name"] = ('COALESCE("name:' + options.locale + '", "name") AS name', ('name:' + options.locale,)) elif options.locale: - columnmap["name"] = ("COALESCE(tags->'name:"+options.locale+'\', "name") AS name',('tags',)) + columnmap["name"] = ("COALESCE(tags->'name:" + options.locale + '\', "name") AS name', ('tags',)) mapped_cols = [i[0] for i in columnmap.values()] numerics = set() # set of number-compared things, like "population<10000" needs population as number, not text @@ -176,21 +175,21 @@ if options.renderer == "mapnik": coast = {} fonts = set() demhack = False - for zoom in xrange (options.minzoom, options.maxzoom+1): + for zoom in xrange(options.minzoom, options.maxzoom + 1): mapniksheet[zoom] = {} zsheet = mapniksheet[zoom] for chooser in style.choosers: if chooser.get_sql_hints(chooser.ruleChains[0].subject, zoom)[1]: - #sys.stderr.write(str(chooser.get_sql_hints(chooser.ruleChains[0][0].subject, zoom)[1])+"\n") + # sys.stderr.write(str(chooser.get_sql_hints(chooser.ruleChains[0][0].subject, zoom)[1])+"\n") styles = chooser.styles[0] - zindex = styles.get("z-index",0) + zindex = styles.get("z-index", 0) if zindex not in zsheet: zsheet[zindex] = [] chooser_entry = {} ttypes = list(set([x.subject for x in chooser.ruleChains])) - sql = "("+ chooser.get_sql_hints(chooser.ruleChains[0].subject,zoom)[1] +")" + sql = "(" + chooser.get_sql_hints(chooser.ruleChains[0].subject, zoom)[1] + ")" sql = sql.split('"') sq = "" odd = True @@ -203,12 +202,12 @@ if options.renderer == "mapnik": chooser_entry["sql"] = sq chooser_entry["style"] = styles - fonts.add(styles.get("font-family","DejaVu Sans Book")) + fonts.add(styles.get("font-family", "DejaVu Sans Book")) chooser_entry["rule"] = [i.conditions for i in chooser.ruleChains if i.test_zoom(zoom)] numerics.update(chooser.get_numerics()) - #print chooser_entry["rule"] - chooser_entry["rulestring"] = " or ".join([ "("+ " and ".join([i.get_mapnik_filter() for i in rule if i.get_mapnik_filter()]) + ")" for rule in chooser_entry["rule"]]) + # print chooser_entry["rule"] + chooser_entry["rulestring"] = " or ".join(["(" + " and ".join([i.get_mapnik_filter() for i in rule if i.get_mapnik_filter()]) + ")" for rule in chooser_entry["rule"]]) chooser_entry["chooser"] = chooser for ttype in ttypes: if ttype == "ele": @@ -220,10 +219,10 @@ if options.renderer == "mapnik": che["type"] = ttype zsheet[zindex].append(che) - #sys.stderr.write(str(numerics)+"\n") - #print mapniksheet + # sys.stderr.write(str(numerics)+"\n") + # print mapniksheet - def add_numerics_to_itags(itags, escape = True): + def add_numerics_to_itags(itags, escape=True): tt = set() nitags = set() if escape: @@ -231,30 +230,26 @@ if options.renderer == "mapnik": else: def escape(i, asname=False): if i in mapped_cols: - return i # already escaped - return '"'+i+'"' + return i # already escaped + return '"' + i + '"' for i in itags: if i in numerics: - tt.add("""(CASE WHEN %s ~ E'^[[:digit:]]+([.][[:digit:]]+)?$' THEN CAST (%s AS FLOAT) ELSE NULL END) as %s__num"""%(escape(i),escape(i),i)) - nitags.add(escape(i, asname = True)) + tt.add("""(CASE WHEN %s ~ E'^[[:digit:]]+([.][[:digit:]]+)?$' THEN CAST (%s AS FLOAT) ELSE NULL END) as %s__num""" % (escape(i), escape(i), i)) + nitags.add(escape(i, asname=True)) itags = nitags itags.update(tt) return itags - - - bgcolor = style.get_style("canvas", {}, options.maxzoom+1)[0].get("fill-color", "") - opacity = style.get_style("canvas", {}, options.maxzoom+1)[0].get("opacity", 1) - hshack = style.get_style("canvas", {}, options.maxzoom+1)[0].get("-x-kot-hs-hack", False) + bgcolor = style.get_style("canvas", {}, options.maxzoom + 1)[0].get("fill-color", "") + opacity = style.get_style("canvas", {}, options.maxzoom + 1)[0].get("opacity", 1) + hshack = style.get_style("canvas", {}, options.maxzoom + 1)[0].get("-x-kot-hs-hack", False) if (opacity == 1) and bgcolor: mfile.write(xml_start(bgcolor)) else: mfile.write(xml_start("transparent")) - - conf_full_layering = style.get_style("canvas", {}, options.maxzoom+1)[0].get("-x-kot-true-layers", "true").lower() == 'true' - + conf_full_layering = style.get_style("canvas", {}, options.maxzoom + 1)[0].get("-x-kot-true-layers", "true").lower() == 'true' for font in fonts: mfile.write(xml_fontset(font, True)) @@ -264,20 +259,20 @@ if options.renderer == "mapnik": ta = zsheet.keys() ta.sort(key=float) demcolors = {} - demramp = {"ground":"", "ocean":""} + demramp = {"ground": "", "ocean": ""} if demhack: for zindex in ta: for entry in zsheet[zindex]: if entry["type"] in ("ele",): - ele = int(entry["rule"][0][0].params[0]) + ele = int(entry["rule"][0][0].params[0]) demcolors[ele] = (whatever_to_hex(entry["style"].get('fill-color', '#ffffff')), entry["style"].get('fill-opacity', '1')) dk = demcolors.keys() dk.sort() for ele in dk: (color, opacity) = demcolors[ele] - demramp["ocean"] += '' %(ele+10701, int(color[1:3],16), int(color[3:5],16), int(color[5:7],16), opacity) - demramp["ground"] += '' %(ele, int(color[1:3],16), int(color[3:5],16), int(color[5:7],16), opacity) + demramp["ocean"] += '' % (ele + 10701, int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16), opacity) + demramp["ground"] += '' % (ele, int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16), opacity) if demhack and zoom >= 7: xml = xml_cleantopo(zoom, x_scale, demramp["ocean"]) @@ -287,7 +282,7 @@ if options.renderer == "mapnik": xml += xml_rule_start() xml += x_scale if "fill-color" in coast[zoom]: - xml += xml_polygonsymbolizer(coast[zoom].get("fill-color", "#ffffff"), relaxedFloat(coast[zoom].get("fill-opacity", "1")), relaxedFloat(coast[zoom].get("smooth","0"))) + xml += xml_polygonsymbolizer(coast[zoom].get("fill-color", "#ffffff"), relaxedFloat(coast[zoom].get("fill-opacity", "1")), relaxedFloat(coast[zoom].get("smooth", "0"))) if "fill-image" in coast[zoom]: xml += xml_polygonpatternsymbolizer(coast[zoom].get("fill-image", "")) xml += xml_rule_end() @@ -314,12 +309,12 @@ if options.renderer == "mapnik": xml = xml_style_start() for entry in zsheet[zindex]: if entry["type"] in ("way", "area", "polygon"): - if ("fill-color" in entry["style"] or "fill-image" in entry["style"]) and (entry["style"].get("fill-position", "foreground")=="background"): + if ("fill-color" in entry["style"] or "fill-image" in entry["style"]) and (entry["style"].get("fill-position", "foreground") == "background"): xml += xml_rule_start() xml += x_scale xml += xml_filter(entry["rulestring"]) if "fill-color" in entry["style"]: - xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), relaxedFloat(entry["style"].get("fill-opacity", "1")), relaxedFloat(entry["style"].get("smooth","0"))) + xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), relaxedFloat(entry["style"].get("fill-opacity", "1")), relaxedFloat(entry["style"].get("smooth", "0"))) if "fill-image" in entry["style"]: xml += xml_polygonpatternsymbolizer(entry["style"].get("fill-image", "")) sql.add(entry["sql"]) @@ -337,9 +332,9 @@ if options.renderer == "mapnik": itags = itags_g if sql: mfile.write(xml_g) - sql = "(" + " OR ".join(sql) + ")"# and way && !bbox!" + sql = "(" + " OR ".join(sql) + ")" # and way && !bbox!" itags = add_numerics_to_itags(itags) - mfile.write(xml_layer("postgis", "polygon", itags, sql, zoom=zoom )) + mfile.write(xml_layer("postgis", "polygon", itags, sql, zoom=zoom)) else: xml_nolayer() @@ -347,36 +342,37 @@ if options.renderer == "mapnik": xml = xml_hillshade(zoom, x_scale) mfile.write(xml) - index_range = range(-6,7) + index_range = range(-6, 7) full_layering = conf_full_layering - if (zoom < 9) or not conf_full_layering : - index_range = (-6,0,6) + if (zoom < 9) or not conf_full_layering: + index_range = (-6, 0, 6) full_layering = False + def check_if_roads_table(rulestring): roads = set([ - "[highway] = 'secondary'", - "[highway] = 'secondary_link'", - "[highway] = 'primary'", - "[highway] = 'primary_link'", - "[highway] = 'trunk'", - "[highway] = 'trunk_link'", - "[highway] = 'motorway'", - "[highway] = 'motorway_link'", - "[boundary] = 'administrative'", - "[railway] " - ]) + "[highway] = 'secondary'", + "[highway] = 'secondary_link'", + "[highway] = 'primary'", + "[highway] = 'primary_link'", + "[highway] = 'trunk'", + "[highway] = 'trunk_link'", + "[highway] = 'motorway'", + "[highway] = 'motorway_link'", + "[boundary] = 'administrative'", + "[railway] " + ]) for a in rulestring.split(') or ('): for r in roads: if r not in a: return False return True for zlayer in index_range: - for layer_type, entry_types in [("line",("way", "line")),("polygon",("way","area"))]: + for layer_type, entry_types in [("line", ("way", "line")), ("polygon", ("way", "area"))]: sql_g = set() there_are_dashed_lines = False itags_g = set() xml_g = "" - roads = (layer_type == 'line') # whether to use planet_osm_roads + roads = (layer_type == 'line') # whether to use planet_osm_roads ## casings pass for zindex in ta: sql = set() @@ -389,7 +385,7 @@ if options.renderer == "mapnik": continue if zlayer != 6 and entry["style"]["-x-kot-layer"] == "top": continue - elif zlayer not in range(-5,6): + elif zlayer not in range(-5, 6): continue if "casing-width" in entry["style"]: xml += xml_rule_start() @@ -397,18 +393,18 @@ if options.renderer == "mapnik": xml += xml_filter(entry["rulestring"]) if not check_if_roads_table(entry["rulestring"]): roads = False - twidth = 2*float(entry["style"].get("casing-width", 1))+float(entry["style"].get("width", 0)); + twidth = 2 * float(entry["style"].get("casing-width", 1)) + float(entry["style"].get("width", 0)) tlinejoin = "round" if twidth < 3: tlinejoin = "miter" xml += xml_linesymbolizer(color=entry["style"].get("casing-color", "black"), - width=twidth, - opacity=relaxedFloat(entry["style"].get("casing-opacity", entry["style"].get("opacity","1"))), - linecap=entry["style"].get("casing-linecap", entry["style"].get("linecap","butt")), - linejoin=entry["style"].get("casing-linejoin", entry["style"].get("linejoin", "round")), - dashes=entry["style"].get("casing-dashes",entry["style"].get("dashes", "")), - smooth=relaxedFloat(entry["style"].get("smooth","0")), - zoom=zoom) + width=twidth, + opacity=relaxedFloat(entry["style"].get("casing-opacity", entry["style"].get("opacity", "1"))), + linecap=entry["style"].get("casing-linecap", entry["style"].get("linecap", "butt")), + linejoin=entry["style"].get("casing-linejoin", entry["style"].get("linejoin", "round")), + dashes=entry["style"].get("casing-dashes", entry["style"].get("dashes", "")), + smooth=relaxedFloat(entry["style"].get("smooth", "0")), + zoom=zoom) sql.add(entry["sql"]) itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom)) @@ -427,26 +423,26 @@ if options.renderer == "mapnik": itags = itags_g if sql: mfile.write(xml_g) - sql = "(" + " OR ".join(sql) + ")"# and way && !bbox!" + sql = "(" + " OR ".join(sql) + ")" # and way && !bbox!" if zlayer == 0 and full_layering: - sql = "("+ sql +') and ("layer" not in ('+ ", ".join(['\'%s\''%i for i in range(-5,6) if i != 0])+") or \"layer\" is NULL)" - elif zlayer <=5 and zlayer >= -5 and full_layering: - sql = "("+ sql +') and "layer" = \'%s\''%zlayer + sql = "(" + sql + ') and ("layer" not in (' + ", ".join(['\'%s\'' % i for i in range(-5, 6) if i != 0]) + ") or \"layer\" is NULL)" + elif zlayer <= 5 and zlayer >= -5 and full_layering: + sql = "(" + sql + ') and "layer" = \'%s\'' % zlayer itags = add_numerics_to_itags(itags) if roads: layer_type = 'roads' - mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom )) + mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom)) else: xml_nolayer() for zindex in ta: - for layer_type, entry_types in [("line",("way", "line")),("polygon",("way","area"))]: + for layer_type, entry_types in [("line", ("way", "line")), ("polygon", ("way", "area"))]: ## lines and polygons pass sql_g = set() there_are_dashed_lines = False there_are_line_patterns = False itags_g = set() - roads = (layer_type == 'line')# whether to use planet_osm_roads + roads = (layer_type == 'line') # whether to use planet_osm_roads xml_g = "" sql = set() @@ -459,17 +455,17 @@ if options.renderer == "mapnik": continue if zlayer != 6 and entry["style"]["-x-kot-layer"] == "top": continue - elif zlayer not in range(-5,6): + elif zlayer not in range(-5, 6): continue - if "width" in entry["style"] or "pattern-image" in entry["style"] or (("fill-color" in entry["style"] or "fill-image" in entry["style"]) and (layer_type == "polygon") and (entry["style"].get("fill-position", "foreground")=="foreground")): + if "width" in entry["style"] or "pattern-image" in entry["style"] or (("fill-color" in entry["style"] or "fill-image" in entry["style"]) and (layer_type == "polygon") and (entry["style"].get("fill-position", "foreground") == "foreground")): xml += xml_rule_start() xml += x_scale xml += xml_filter(entry["rulestring"]) if not check_if_roads_table(entry["rulestring"]): roads = False - if layer_type == "polygon" and (entry["style"].get("fill-position", "foreground")=="foreground"): + if layer_type == "polygon" and (entry["style"].get("fill-position", "foreground") == "foreground"): if "fill-color" in entry["style"]: - xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), relaxedFloat(entry["style"].get("fill-opacity", "1")), relaxedFloat(entry["style"].get("smooth","0"))) + xml += xml_polygonsymbolizer(entry["style"].get("fill-color", "black"), relaxedFloat(entry["style"].get("fill-opacity", "1")), relaxedFloat(entry["style"].get("smooth", "0"))) if "fill-image" in entry["style"]: xml += xml_polygonpatternsymbolizer(entry["style"].get("fill-image", "")) if "width" in entry["style"]: @@ -488,16 +484,16 @@ if options.renderer == "mapnik": tlinecap = entry["style"].get("linecap", tlinecap) xml += xml_linesymbolizer(color=entry["style"].get("color", "black"), - width=twidth, - opacity=relaxedFloat(entry["style"].get("opacity", "1")), - linecap=tlinecap, - linejoin=tlinejoin, - dashes=entry["style"].get("dashes", ""), - smooth=relaxedFloat(entry["style"].get("smooth","0")), - zoom=zoom) + width=twidth, + opacity=relaxedFloat(entry["style"].get("opacity", "1")), + linecap=tlinecap, + linejoin=tlinejoin, + dashes=entry["style"].get("dashes", ""), + smooth=relaxedFloat(entry["style"].get("smooth", "0")), + zoom=zoom) if entry["style"].get("dashes", ""): there_are_dashed_lines = True - #print "dashes!!!" + # print "dashes!!!" if "pattern-image" in entry["style"]: there_are_line_patterns = True if entry["style"]["pattern-image"] == "arrows": @@ -507,27 +503,27 @@ if options.renderer == "mapnik": fname = entry["style"]["pattern-image"] try: im = Image.open(icons_path + fname).convert("RGBA") - fname = "f"+fname + fname = "f" + fname if "pattern-rotate" in entry["style"]: im = im.rotate(relaxedFloat(entry["style"]["pattern-rotate"])) - fname = "r"+str(relaxedFloat(entry["style"]["pattern-rotate"]))+fname + fname = "r" + str(relaxedFloat(entry["style"]["pattern-rotate"])) + fname if "pattern-scale" in entry["style"]: - sc = relaxedFloat(entry["style"]["pattern-scale"])*1. - ns = (max(int(round(im.size[0]*sc)),1), max(int(round(im.size[1]*sc)),1)) + sc = relaxedFloat(entry["style"]["pattern-scale"]) * 1. + ns = (max(int(round(im.size[0] * sc)), 1), max(int(round(im.size[1] * sc)), 1)) im = im.resize(ns, Image.BILINEAR) - fname = "z"+str(sc)+fname + fname = "z" + str(sc) + fname if "pattern-spacing" in entry["style"]: - im2 = Image.new("RGBA", (im.size[0]+int(relaxedFloat(entry["style"]["pattern-spacing"])),im.size[1])) - im2.paste(im,(0,0)) + im2 = Image.new("RGBA", (im.size[0] + int(relaxedFloat(entry["style"]["pattern-spacing"])), im.size[1])) + im2.paste(im, (0, 0)) im = im2 - fname = "s"+str(int(relaxedFloat(entry["style"]["pattern-spacing"])))+fname - if not os.path.exists(icons_path+"komap/"): - os.makedirs(icons_path+"komap/") - if not os.path.exists(icons_path+"komap/"+fname): - im.save(icons_path+"komap/"+fname, "PNG") - xml += xml_linepatternsymbolizer("komap/"+fname) + fname = "s" + str(int(relaxedFloat(entry["style"]["pattern-spacing"]))) + fname + if not os.path.exists(icons_path + "komap/"): + os.makedirs(icons_path + "komap/") + if not os.path.exists(icons_path + "komap/" + fname): + im.save(icons_path + "komap/" + fname, "PNG") + xml += xml_linepatternsymbolizer("komap/" + fname) except: - print >> sys.stderr, "Error writing to ", icons_path+"komap/"+fname + print >> sys.stderr, "Error writing to ", icons_path + "komap/" + fname else: xml += xml_linepatternsymbolizer(entry["style"]["pattern-image"]) sql.add(entry["sql"]) @@ -546,38 +542,38 @@ if options.renderer == "mapnik": itags = itags_g if sql: mfile.write(xml_g) - sql = "(" + " OR ".join(sql) + ")"# and way && !bbox!" + sql = "(" + " OR ".join(sql) + ")" # and way && !bbox!" if zlayer == 0 and full_layering: - sql = "("+ sql +') and ("layer" not in ('+ ", ".join(['\'%s\''%i for i in range(-5,6) if i != 0])+") or \"layer\" is NULL)" - elif zlayer <=5 and zlayer >= -5 and full_layering: - sql = "("+ sql +') and "layer" = \'%s\''%zlayer + sql = "(" + sql + ') and ("layer" not in (' + ", ".join(['\'%s\'' % i for i in range(-5, 6) if i != 0]) + ") or \"layer\" is NULL)" + elif zlayer <= 5 and zlayer >= -5 and full_layering: + sql = "(" + sql + ') and "layer" = \'%s\'' % zlayer oitags = itags itags = add_numerics_to_itags(itags) if layer_type == "polygon" and there_are_line_patterns: itags = ", ".join(itags) - oitags = '"'+ "\", \"".join(oitags) +'"' - sqlz = """SELECT %s, ST_ForceRHR(way) as way from %spolygon where (%s) and way && !bbox! and ST_IsValid(way)"""%(itags, libkomapnik.table_prefix ,sql) + oitags = '"' + "\", \"".join(oitags) + '"' + sqlz = """SELECT %s, ST_ForceRHR(way) as way from %spolygon where (%s) and way && !bbox! and ST_IsValid(way)""" % (itags, libkomapnik.table_prefix , sql) mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom=zoom)) #### FIXME: Performance degrades painfully on large lines ST_Union. Gotta find workaround :( - #if layer_type == "polygon" and there_are_dashed_lines: - #itags = ", ".join(itags) - #oitags = '"'+ "\", \"".join(oitags) +'"' - #sqlz = """select %s, ST_LineMerge(ST_Union(way)) as way from + # if layer_type == "polygon" and there_are_dashed_lines: + # itags = ", ".join(itags) + # oitags = '"'+ "\", \"".join(oitags) +'"' + # sqlz = """select %s, ST_LineMerge(ST_Union(way)) as way from #(SELECT %s, ST_Boundary(way) as way from planet_osm_polygon where (%s) and way && !bbox! and ST_IsValid(way) ) tex - #group by %s + # group by %s #"""%(itags,oitags,sql,oitags) elif layer_type == "line" and there_are_dashed_lines and zoom < 10: - itags = ", ".join(itags) # FIXME: wrong when working with hstore - oitags = '"'+ "\", \"".join(oitags) +'"' + itags = ", ".join(itags) # FIXME: wrong when working with hstore + oitags = '"' + "\", \"".join(oitags) + '"' sqlz = """select %s, ST_LineMerge(ST_Union(way)) as way from (SELECT %s, ST_SnapToGrid(way, %s) as way from %sline where way && !bbox! and (%s)) as tex group by %s - """%(oitags, itags,pixel_size_at_zoom(zoom,1.5),libkomapnik.table_prefix,sql,oitags) - mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom=zoom )) + """ % (oitags, itags, pixel_size_at_zoom(zoom, 1.5), libkomapnik.table_prefix, sql, oitags) + mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom=zoom)) else: if roads: layer_type = 'roads' - mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom )) + mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom)) else: xml_nolayer() @@ -588,7 +584,7 @@ if options.renderer == "mapnik": xml_g = "" prevtype = "" for zindex in ta: - for layer_type, entry_types in [("point", ("node", "point")),("line",("way", "line")), ("polygon",("way","area"))]: + for layer_type, entry_types in [("point", ("node", "point")), ("line", ("way", "line")), ("polygon", ("way", "area"))]: sql = set() itags = set() style_started = False @@ -600,9 +596,9 @@ if options.renderer == "mapnik": if prevtype != layer_type: if sql_g: mfile.write(xml_g) - sql_g = "(" + " OR ".join(sql_g) + ")"# and way && !bbox!" + sql_g = "(" + " OR ".join(sql_g) + ")" # and way && !bbox!" itags_g = add_numerics_to_itags(itags_g) - mfile.write(xml_layer("postgis", prevtype, itags_g, sql_g, zoom=zoom )) + mfile.write(xml_layer("postgis", prevtype, itags_g, sql_g, zoom=zoom)) sql_g = set() itags_g = set() xml_g = "" @@ -618,13 +614,13 @@ if options.renderer == "mapnik": xml += x_scale xml += xml_filter(entry["rulestring"]) xml += xml_pointsymbolizer( - path=entry["style"].get("icon-image", ""), - width=entry["style"].get("icon-width", ""), - height=entry["style"].get("icon-height", ""), - opacity=relaxedFloat(entry["style"].get("opacity", "1"))) - if ("text" in entry["style"] and entry["style"].get("text-position","center")=='center'): + path=entry["style"].get("icon-image", ""), + width=entry["style"].get("icon-width", ""), + height=entry["style"].get("icon-height", ""), + opacity=relaxedFloat(entry["style"].get("opacity", "1"))) + if ("text" in entry["style"] and entry["style"].get("text-position", "center") == 'center'): ttext = entry["style"]["text"].extract_tags().pop() - sql.add("(("+entry["sql"]+") and "+escape_sql_column(ttext) + " is NULL)") + sql.add("((" + entry["sql"] + ") and " + escape_sql_column(ttext) + " is NULL)") itags.add(ttext) if ttext in columnmap: itags.update(columnmap[ttext][1]) @@ -645,24 +641,24 @@ if options.renderer == "mapnik": xml_nosubstyle() if sql_g: mfile.write(xml_g) - sql_g = "(" + " OR ".join(sql_g) + ")"# and way && !bbox!" + sql_g = "(" + " OR ".join(sql_g) + ")" # and way && !bbox!" itags_g = add_numerics_to_itags(itags_g) - mfile.write(xml_layer("postgis", prevtype, itags_g, sql_g, zoom=zoom )) + mfile.write(xml_layer("postgis", prevtype, itags_g, sql_g, zoom=zoom)) else: xml_nolayer() ta.reverse() for zindex in ta: - for layer_type, entry_types in [("point", ("node", "point")), ("polygon",("way","area")), ("line",("way", "line"))]: - for placement in ("center","line"): + for layer_type, entry_types in [("point", ("node", "point")), ("polygon", ("way", "area")), ("line", ("way", "line"))]: + for placement in ("center", "line"): ## text pass collhere = set() for entry in zsheet[zindex]: - if entry["type"] in entry_types:#, "node", "line", "point"): - if ("text" in entry["style"] or "shield-text" in entry["style"]) and entry["style"].get("text-position","center")==placement: - csb = entry["style"].get("collision-sort-by",None) - cso = entry["style"].get("collision-sort-order","desc") - collhere.add((csb,cso)) + if entry["type"] in entry_types: # , "node", "line", "point"): + if ("text" in entry["style"] or "shield-text" in entry["style"]) and entry["style"].get("text-position", "center") == placement: + csb = entry["style"].get("collision-sort-by", None) + cso = entry["style"].get("collision-sort-order", "desc") + collhere.add((csb, cso)) for snap_to_street in ('true', 'false'): for (csb, cso) in collhere: sql = set() @@ -670,68 +666,68 @@ if options.renderer == "mapnik": texttags = set() xml = xml_style_start() for entry in zsheet[zindex]: - if entry["type"] in entry_types and csb == entry["style"].get("collision-sort-by",None) and cso == entry["style"].get("collision-sort-order","desc") and snap_to_street == entry["style"].get("-x-kot-snap-to-street","false"): + if entry["type"] in entry_types and csb == entry["style"].get("collision-sort-by", None) and cso == entry["style"].get("collision-sort-order", "desc") and snap_to_street == entry["style"].get("-x-kot-snap-to-street", "false"): if "shield-text" in entry["style"] and "shield-image" in entry["style"]: ttext = entry["style"]["shield-text"].extract_tags().pop() texttags.add(ttext) - tface = entry["style"].get("shield-font-family","DejaVu Sans Book") - tsize = entry["style"].get("shield-font-size","10") - tcolor = entry["style"].get("shield-text-color","#000000") - toverlap= entry["style"].get("text-allow-overlap",entry["style"].get("allow-overlap","false")) - tdistance= relaxedFloat(entry["style"].get("-x-kot-min-distance","20")) - twrap= relaxedFloat(entry["style"].get("shield-max-width",25)) - talign= entry["style"].get("shield-text-align","center") - topacity= relaxedFloat(entry["style"].get("shield-text-opacity",entry["style"].get("opacity","1"))) - toffset= relaxedFloat(entry["style"].get("shield-text-offset","0")) - ttransform = entry["style"].get("shield-text-transform","none") - tspacing = entry["style"].get("shield-spacing","500") + tface = entry["style"].get("shield-font-family", "DejaVu Sans Book") + tsize = entry["style"].get("shield-font-size", "10") + tcolor = entry["style"].get("shield-text-color", "#000000") + toverlap = entry["style"].get("text-allow-overlap", entry["style"].get("allow-overlap", "false")) + tdistance = relaxedFloat(entry["style"].get("-x-kot-min-distance", "20")) + twrap = relaxedFloat(entry["style"].get("shield-max-width", 25)) + talign = entry["style"].get("shield-text-align", "center") + topacity = relaxedFloat(entry["style"].get("shield-text-opacity", entry["style"].get("opacity", "1"))) + toffset = relaxedFloat(entry["style"].get("shield-text-offset", "0")) + ttransform = entry["style"].get("shield-text-transform", "none") + tspacing = entry["style"].get("shield-spacing", "500") xml += xml_rule_start() xml += x_scale xml += xml_filter(entry["rulestring"]) xml += xml_shieldsymbolizer( - entry["style"].get("shield-image", ""), - "", - "", - ttext,tface,tsize,tcolor, "#000000", 0, "center", - toffset,toverlap,tdistance,twrap,talign,topacity, ttransform, "false", tspacing) + entry["style"].get("shield-image", ""), + "", + "", + ttext, tface, tsize, tcolor, "#000000", 0, "center", + toffset, toverlap, tdistance, twrap, talign, topacity, ttransform, "false", tspacing) sql.add(entry["sql"]) itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom)) xml += xml_rule_end() - if "text" in entry["style"] and entry["style"].get("text-position","center")==placement: + if "text" in entry["style"] and entry["style"].get("text-position", "center") == placement: ttext = entry["style"]["text"].extract_tags().pop() texttags.add(ttext) - 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= relaxedFloat(entry["style"].get("text-halo-radius","0")) - tplace= entry["style"].get("text-position","center") - toffset= relaxedFloat(entry["style"].get("text-offset","0")) - toverlap= entry["style"].get("text-allow-overlap",entry["style"].get("allow-overlap","false")) - tdistance= relaxedFloat(entry["style"].get("-x-kot-min-distance","20")) - twrap= relaxedFloat(entry["style"].get("max-width",256)) - talign= entry["style"].get("text-align","center") - topacity= relaxedFloat(entry["style"].get("text-opacity",entry["style"].get("opacity","1"))) - tpos = entry["style"].get("text-placement","X") - ttransform = entry["style"].get("text-transform","none") - tspacing = entry["style"].get("text-spacing","4096") + 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 = relaxedFloat(entry["style"].get("text-halo-radius", "0")) + tplace = entry["style"].get("text-position", "center") + toffset = relaxedFloat(entry["style"].get("text-offset", "0")) + toverlap = entry["style"].get("text-allow-overlap", entry["style"].get("allow-overlap", "false")) + tdistance = relaxedFloat(entry["style"].get("-x-kot-min-distance", "20")) + twrap = relaxedFloat(entry["style"].get("max-width", 256)) + talign = entry["style"].get("text-align", "center") + topacity = relaxedFloat(entry["style"].get("text-opacity", entry["style"].get("opacity", "1"))) + tpos = entry["style"].get("text-placement", "X") + ttransform = entry["style"].get("text-transform", "none") + tspacing = entry["style"].get("text-spacing", "4096") xml += xml_rule_start() xml += x_scale xml += xml_filter(entry["rulestring"]) - if "icon-image" in entry["style"] and entry["style"].get("text-position","center")=='center': + if "icon-image" in entry["style"] and entry["style"].get("text-position", "center") == 'center': xml += xml_shieldsymbolizer( - entry["style"].get("icon-image", ""), - entry["style"].get("icon-width", ""), - entry["style"].get("icon-height", ""), - ttext,tface,tsize,tcolor, thcolor, thradius, tplace, - toffset,toverlap,tdistance,twrap,talign,topacity, ttransform) + entry["style"].get("icon-image", ""), + entry["style"].get("icon-width", ""), + entry["style"].get("icon-height", ""), + ttext, tface, tsize, tcolor, thcolor, thradius, tplace, + toffset, toverlap, tdistance, twrap, talign, topacity, ttransform) else: - xml += xml_textsymbolizer(ttext,tface,tsize,tcolor, thcolor, thradius, tplace, toffset,toverlap,tdistance,twrap,talign,topacity,tpos,ttransform,tspacing) + xml += xml_textsymbolizer(ttext, tface, tsize, tcolor, thcolor, thradius, tplace, toffset, toverlap, tdistance, twrap, talign, topacity, tpos, ttransform, tspacing) sql.add(entry["sql"]) itags.update(entry["chooser"].get_interesting_tags(entry["type"], zoom)) xml += xml_rule_end() @@ -744,7 +740,7 @@ if options.renderer == "mapnik": if cso != "desc": cso = "asc" itags.add(csb) - order = """ order by (CASE WHEN "%s" ~ E'^[[:digit:]]+([.][[:digit:]]+)?$' THEN to_char(CAST ("%s" AS FLOAT) ,'000000000000000.99999999999') else "%s" end) %s nulls last """%(csb,csb,csb,cso) + order = """ order by (CASE WHEN "%s" ~ E'^[[:digit:]]+([.][[:digit:]]+)?$' THEN to_char(CAST ("%s" AS FLOAT) ,'000000000000000.99999999999') else "%s" end) %s nulls last """ % (csb, csb, csb, cso) mfile.write(xml) @@ -754,20 +750,20 @@ if options.renderer == "mapnik": add_tags.update(columnmap[t][1]) texttags.update(columnmap[t][1]) - oitags = itags.union(add_tags) # SELECT: (tags->'mooring') as "mooring" - oitags = ", ".join([ escape_sql_column(i, asname=True) for i in oitags]) + oitags = itags.union(add_tags) # SELECT: (tags->'mooring') as "mooring" + oitags = ", ".join([escape_sql_column(i, asname=True) for i in oitags]) - goitags = itags.union(add_tags) # GROUP BY: (tags->'mooring') - goitags = ", ".join([ escape_sql_column(i) for i in goitags]) + goitags = itags.union(add_tags) # GROUP BY: (tags->'mooring') + goitags = ", ".join([escape_sql_column(i) for i in goitags]) fitags = [columnmap.get(i, (i,))[0] for i in itags] - #fitags = add_numerics_to_itags(itags) - itags = add_numerics_to_itags(fitags) # population => {population, population__num} - neitags = add_numerics_to_itags(fitags, escape = False) # for complex polygons, no escapng needed + # fitags = add_numerics_to_itags(itags) + itags = add_numerics_to_itags(fitags) # population => {population, population__num} + neitags = add_numerics_to_itags(fitags, escape=False) # for complex polygons, no escapng needed del fitags - ttext = " OR ".join([escape_sql_column(i)+ " is not NULL" for i in texttags]) + ttext = " OR ".join([escape_sql_column(i) + " is not NULL" for i in texttags]) if placement == "center" and layer_type == "polygon" and snap_to_street == 'false': sqlz = " OR ".join(sql) @@ -781,7 +777,7 @@ if options.renderer == "mapnik": sqlz = """select %s, way from %s%s where (%s) and (%s) and (way_area > %s) and way && ST_Expand(!bbox!,3000) %s way_area desc - """%(itags,libkomapnik.table_prefix,layer_type,ttext,sqlz,pixel_size_at_zoom(zoom,3)**2, order) + """ % (itags, libkomapnik.table_prefix, layer_type, ttext, sqlz, pixel_size_at_zoom(zoom, 3) ** 2, order) else: sqlz = """select %s, way from ( @@ -791,10 +787,10 @@ if options.renderer == "mapnik": from %s%s p where (%s) and way_area > %s and p.way && ST_Expand(!bbox!,%s) and (%s)) p group by %s) p %s ST_Area(p.way) desc - """%(neitags,pixel_size_at_zoom(zoom,9),pixel_size_at_zoom(zoom,10),oitags, - libkomapnik.table_prefix,layer_type,ttext,pixel_size_at_zoom(zoom,5)**2,max(pixel_size_at_zoom(zoom,20),3000),sqlz,goitags,order) + """ % (neitags, pixel_size_at_zoom(zoom, 9), pixel_size_at_zoom(zoom, 10), oitags, + libkomapnik.table_prefix, layer_type, ttext, pixel_size_at_zoom(zoom, 5) ** 2, max(pixel_size_at_zoom(zoom, 20), 3000), sqlz, goitags, order) - mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom )) + mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom)) elif layer_type == "line" and zoom < 16 and snap_to_street == 'false': sqlz = " OR ".join(sql) itags = ", ".join(itags) @@ -802,14 +798,13 @@ if options.renderer == "mapnik": order = "order by" else: order += ", " - #itags = "\""+ itags+"\"" + # itags = "\""+ itags+"\"" sqlz = """select * from (select %s, ST_Simplify(ST_LineMerge(ST_Union(way)),%s) as way from (SELECT * from %sline where way && ST_Expand(!bbox!,%s) and (%s) and (%s)) as tex group by %s) p where ST_Length(p.way) > %s %s ST_Length(p.way) desc - """%(itags,pixel_size_at_zoom(zoom,3),libkomapnik.table_prefix,max(pixel_size_at_zoom(zoom,20),3000),ttext,sqlz,goitags,pixel_size_at_zoom(zoom,4),order) - mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom=zoom )) - + """ % (itags, pixel_size_at_zoom(zoom, 3), libkomapnik.table_prefix, max(pixel_size_at_zoom(zoom, 20), 3000), ttext, sqlz, goitags, pixel_size_at_zoom(zoom, 4), order) + mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom=zoom)) elif snap_to_street == 'true': sqlz = " OR ".join(sql) @@ -878,13 +873,12 @@ if options.renderer == "mapnik": from %s%s h where (%s) and (%s) and way && ST_Expand(!bbox!,3000) %s - """%(itags, libkomapnik.db_srid, libkomapnik.table_prefix, libkomapnik.db_srid, libkomapnik.table_prefix, libkomapnik.table_prefix, layer_type, ttext,sqlz, order) - mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom )) - + """ % (itags, libkomapnik.db_srid, libkomapnik.table_prefix, libkomapnik.db_srid, libkomapnik.table_prefix, libkomapnik.table_prefix, layer_type, ttext, sqlz, order) + mfile.write(xml_layer("postgis-process", layer_type, itags, sqlz, zoom)) else: - sql = "(" + " OR ".join(sql) + ") %s"%(order)#and way && ST_Expand(!bbox!,%s), max(pixel_size_at_zoom(zoom,20),3000), - mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom )) + sql = "(" + " OR ".join(sql) + ") %s" % (order) # and way && ST_Expand(!bbox!,%s), max(pixel_size_at_zoom(zoom,20),3000), + mfile.write(xml_layer("postgis", layer_type, itags, sql, zoom=zoom)) else: xml_nolayer() diff --git a/src/libkojs.py b/src/libkojs.py index b14845c..bbb3536 100644 --- a/src/libkojs.py +++ b/src/libkojs.py @@ -1,5 +1,5 @@ def komap_js(mfile, style): - subjs = {"canvas": ("canvas",),"way": ("Polygon","LineString"), "line":("Polygon","LineString"), "area": ("Polygon",), "node": ("Point",), "*":("Point","Polygon","LineString"), "":("Point","Polygon","LineString"), } + subjs = {"canvas": ("canvas",), "way": ("Polygon", "LineString"), "line": ("Polygon", "LineString"), "area": ("Polygon",), "node": ("Point",), "*": ("Point", "Polygon", "LineString"), "": ("Point", "Polygon", "LineString"), } mfile.write("function restyle (prop, zoom, type){") mfile.write("style = new Object;") mfile.write('style["default"] = new Object;') @@ -9,8 +9,8 @@ def komap_js(mfile, style): for i in chooser.ruleChains: if condition: condition += "||" - rule = " zoom >= %s && zoom <= %s"%(i.minZoom, i.maxZoom) - for z in i.conditions: + rule = " zoom >= %s && zoom <= %s" % (i.minZoom, i.maxZoom) + for z in i.conditions: t = z.type params = z.params if params[0] == "::class": @@ -19,39 +19,39 @@ def komap_js(mfile, style): if rule: rule += " && " if t == 'eq': - rule += 'prop["%s"] == "%s"'%(params[0], params[1]) + rule += 'prop["%s"] == "%s"' % (params[0], params[1]) if t == 'ne': - rule += 'prop["%s"] != "%s"'%(params[0], params[1]) + rule += 'prop["%s"] != "%s"' % (params[0], params[1]) if t == 'regex': - rule += 'prop["%s"].match(RegExp("%s"))'%(params[0], params[1]) + rule += 'prop["%s"].match(RegExp("%s"))' % (params[0], params[1]) if t == 'true': - rule += 'prop["%s"] == "yes"'%(params[0]) + rule += 'prop["%s"] == "yes"' % (params[0]) if t == 'untrue': - rule += 'prop["%s"] != "yes"'%(params[0]) + rule += 'prop["%s"] != "yes"' % (params[0]) if t == 'set': - rule += '"%s" in prop'%(params[0]) + rule += '"%s" in prop' % (params[0]) if t == 'unset': - rule += '!("%s"in prop)'%(params[0]) + rule += '!("%s"in prop)' % (params[0]) if t == '<': - rule += 'prop["%s"] < %s'%(params[0], params[1]) + rule += 'prop["%s"] < %s' % (params[0], params[1]) if t == '<=': - rule += 'prop["%s"] <= %s'%(params[0], params[1]) + rule += 'prop["%s"] <= %s' % (params[0], params[1]) if t == '>': - rule += 'prop["%s"] > %s'%(params[0], params[1]) + rule += 'prop["%s"] > %s' % (params[0], params[1]) if t == '>=': - rule += 'prop["%s"] >= %s'%(params[0], params[1]) + rule += 'prop["%s"] >= %s' % (params[0], params[1]) if rule: rule = "&&" + rule - condition += "(("+"||".join(['type == "%s"'%z for z in subjs[i.subject]])+") "+ rule + ")" + condition += "((" + "||".join(['type == "%s"' % z for z in subjs[i.subject]]) + ") " + rule + ")" styles = "" if subclass != "default": - styles = 'if(!("%s" in style)){style["%s"] = new Object;}'%(subclass,subclass) + 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 + ';' + styles += 'style["' + subclass + '"]["' + k + '"] = ' + v + ';' except: - styles += 'style["'+subclass+'"]["'+k+'"] = "' + v + '";' - mfile.write("if(%s) {%s};\n"%(condition,styles)) + styles += 'style["' + subclass + '"]["' + k + '"] = "' + v + '";' + mfile.write("if(%s) {%s};\n" % (condition, styles)) mfile.write("return style;}") diff --git a/src/libkomapnik.py b/src/libkomapnik.py index e77e789..9aa8fd2 100644 --- a/src/libkomapnik.py +++ b/src/libkomapnik.py @@ -42,29 +42,31 @@ substyles = [] last_id = 0 -def get_id(i = 0): + +def get_id(i=0): global last_id last_id += i return last_id -def zoom_to_scaledenom(z1,z2=False): +def zoom_to_scaledenom(z1, z2=False): """ Converts zoom level to mapnik's scaledenominator pair for EPSG:3857 """ if not z2: z2 = z1 s = 279541132.014 - z1 = (s/(2**(z1-1))+s/(2**(z1-2)))/2 - z2 = (s/(2**(z2-1))+s/(2**z2))/2 - #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 pixel_size_at_zoom(z, l=1): """ Converts l pixels on tiles into length on zoom z """ - return int(math.ceil(l* 20037508.342789244 / 256 * 2 / (2**z))) + return int(math.ceil(l * 20037508.342789244 / 256 * 2 / (2 ** z))) def xml_fontset(name, unicode=True): @@ -74,30 +76,30 @@ def xml_fontset(name, unicode=True): %s - """%(name, name, unicode) + """ % (name, name, unicode) def xml_pointsymbolizer(path="", width="", height="", opacity=1, overlap="false"): if width: - width =' width="%s" '%width + width = ' width="%s" ' % width if height: - height =' height="%s" '%height + height = ' height="%s" ' % height return """ """\ - %(os.path.join(icons_path, path), width, height, opacity, overlap) + % (os.path.join(icons_path, path), width, height, opacity, overlap) def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt", linejoin="round", dashes="", smooth=0, zoom=200): color = nicecolor(color) - linecap = {"none":"butt",}.get(linecap.lower(), linecap) + linecap = {"none": "butt", }.get(linecap.lower(), linecap) if dashes: - dashes = 'stroke-dasharray="%s"'%(dashes) + dashes = 'stroke-dasharray="%s"' % (dashes) else: dashes = "" if smooth: - smooth = 'smooth="%s"'%(smooth) + smooth = 'smooth="%s"' % (smooth) else: smooth = "" @@ -106,75 +108,79 @@ def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt", # rasterizer = ' rasterizer="fast"' return """ - """%(rasterizer, smooth, color, float(width), float(opacity), linejoin, linecap, dashes) + """ % (rasterizer, smooth, color, float(width), float(opacity), linejoin, linecap, dashes) def xml_polygonsymbolizer(color="#000000", opacity="1", smooth='0'): color = nicecolor(color) if smooth: - smooth = 'smooth="%s"'%(smooth) + smooth = 'smooth="%s"' % (smooth) else: smooth = "" return """ - """%(color, float(opacity), smooth) + """ % (color, float(opacity), smooth) + def xml_polygonpatternsymbolizer(file=""): return """ - """%(os.path.join(icons_path,file)) + """ % (os.path.join(icons_path, file)) def xml_linepatternsymbolizer(file=""): return """ - """%(os.path.join(icons_path,file)) + """ % (os.path.join(icons_path, file)) def xml_textsymbolizer( - text="name",face="DejaVu Sans Book",size="10",color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", pos="X", transform = "none", spacing="4096"): + text="name", face="DejaVu Sans Book", size="10", color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", pos="X", transform="none", spacing="4096"): color = nicecolor(color) halo_color = nicecolor(halo_color) - pos = pos.replace("exact", "X").replace("any","S, E, X, N, W, NE, SE, NW, SW").split(",") - pos.extend([str(int(float(x)*text_scale)) for x in size.split(",")]) + pos = pos.replace("exact", "X").replace("any", "S, E, X, N, W, NE, SE, NW, SW").split(",") + pos.extend([str(int(float(x) * text_scale)) for x in size.split(",")]) pos = ",".join(pos) - size = str(int(float(size.split(",")[0])*text_scale)) - + size = str(int(float(size.split(",")[0]) * text_scale)) placement = {"center": "interior"}.get(placement.lower(), placement) align = {"center": "middle"}.get(align.lower(), align) dy = int(float(offset)) dx = 0 - if align in ("right",'left'): + if align in ("right", 'left'): dx = dy dy = 0 return """ [%s] - """%(face,int(float(size)),color,halo_color,halo_radius,placement,dx,dy,overlap,wrap_width,distance,align,opacity,pos, transform, spacing,text) + """ % (face, int(float(size)), color, halo_color, halo_radius, placement, dx, dy, overlap, wrap_width, distance, align, opacity, pos, transform, spacing, text) + def xml_shieldsymbolizer(path="", width="", height="", - text="name",face="DejaVu Sans Book",size="10",color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", transform="none", unlock_image='true', spacing='500'): + text="name", face="DejaVu Sans Book", size="10", color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", transform="none", unlock_image='true', spacing='500'): color = nicecolor(color) halo_color = nicecolor(halo_color) placement = {"center": "point"}.get(placement.lower(), placement) align = {"center": "middle"}.get(align.lower(), align) size = size.split(",")[0] if width: - width =' width="%s" '%width + width = ' width="%s" ' % width if height: - height =' height="%s" '%height + height = ' height="%s" ' % height return """ [%s] - """%(icons_path, \ - path, width, height,face,int(float(size)*text_scale),color,halo_color,halo_radius,placement,offset,overlap,wrap_width,distance,align,opacity, transform, unlock_image, spacing,text ) + """ % (icons_path, + path, width, height, face, int(float(size) * text_scale), color, halo_color, halo_radius, placement, offset, overlap, wrap_width, distance, align, opacity, transform, unlock_image, spacing, text) + def xml_filter(string): return """ - %s"""%string + %s""" % string + def xml_scaledenominator(z1, z2=False): - zz1, zz2 = zoom_to_scaledenom(z1,z2) + zz1, zz2 = zoom_to_scaledenom(z1, z2) return """ %s - %s"""%(zz1,zz2,z1,z2) + %s""" % (zz1, zz2, z1, z2) + def xml_start(bgcolor="transparent"): if bgcolor != "transparent": @@ -182,7 +188,8 @@ def xml_start(bgcolor="transparent"): return """ - """%(bgcolor, map_proj) + """ % (bgcolor, map_proj) + def xml_end(): return """ @@ -194,20 +201,24 @@ def xml_style_start(): layer_id = get_id(1) substyles.append(layer_id) return """ - """ + def xml_rule_start(): return """ """ + def xml_rule_end(): return """ """ + def xml_cleantopo(zoom, x_scale, demramp): return """