def r_bbox(layer, bbox): corrfile = config.tiles_cache + layer.get("prefix", "")+ "/rectify.txt" srs = layer["proj"] if not os.path.exists(corrfile): return bbox a,b,c,d = projections.from4326(bbox,srs) cx, cy = (a+c)/2, (b+d)/2 cx1,cy1 = projections.from4326(rectify(layer,projections.to4326((cx,cy), srs)),srs) a1,b1 = projections.from4326(rectify(layer,projections.to4326((a,b), srs)),srs) c1,d1 = projections.from4326(rectify(layer,projections.to4326((c,d), srs)),srs) dx,dy = ((cx1-cx)+(a1-a)+(c1-c))/3, ((cy1-cy)+(b1-b)+(d1-d))/3 # print >> sys.stderr, dx,dy # sys.stderr.flush() return projections.to4326((a+dx,b+dy,c+dx,d+dy),srs)
def main(): if len(sys.argv) != 3: return 0 segments = int(sys.argv[2]) pointlist = (sys.argv[1].split(';')) coordlist = [] for point in pointlist: coords = point.split(',') coordlist.append( projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857")) if len(coordlist) < 3: sys.stdout.write("<!--Too few control points-->") return 0 if segments == 0: # optimal number of segments for i in range(0, len(coordlist) - 2): P1 = coordlist[i] P2 = coordlist[i + 1] P1P2 = (P2[0] - P1[0], P2[1] - P1[1]) P1P2abs = math.sqrt(P1P2[0] * P1P2[0] + P1P2[1] * P1P2[1]) segments += math.ceil(math.log(P1P2abs, 4)) # cat's magic formula segments = int(segments) tData = OsmData() wayid = tData.addway() step = 1.0 / segments for i in range(segments + 1): t = step * i node = projections.to4326(getpoint(coordlist, t), "EPSG:3857") nodeid = tData.addnode() tData.nodes[nodeid][LON] = node[0] tData.nodes[nodeid][LAT] = node[1] tData.ways[wayid][REF].append(nodeid) tData.addcomment("Done.") tData.write(sys.stdout) return 0
def treplace(nodedata, rdata, rwayid, tdata, twayid, reference, target): rway = rdata.ways[rwayid] tway = tdata.ways[twayid] newtwayref = [] rtmap = {} for i, ref in enumerate(rway[REF]): if rtmap.get(ref) == None: if i < len(tway[REF])-1: node = nodedata.nodes[tway[REF][i]] node[ACTION] = MODIFY newtwayref.append(tway[REF][i]) rtmap[ref] = tway[REF][i] else: nodeid = nodedata.addnode() node = nodedata.nodes[nodeid] newtwayref.append(nodeid) rtmap[ref] = nodeid angle = math.radians(reference[0] - target[0]) mrefnode = projections.from4326((nodedata.nodes[ref][LON], nodedata.nodes[ref][LAT]), "EPSG:3857") mreference = projections.from4326((reference[1][0], reference[1][1]), "EPSG:3857") maboutnull = (mrefnode[0] - mreference[0], mrefnode[1] - mreference[1]) mrotated = (maboutnull[0] * math.cos(angle) - maboutnull[1] * math.sin(angle), maboutnull[0] * math.sin(angle) + maboutnull[1] * math.cos(angle)) mtarget = projections.from4326(target[1], "EPSG:3857") result = projections.to4326((mtarget[0] + mrotated[0], mtarget[1] + mrotated[1]), "EPSG:3857") node[LON] = result[0] node[LAT] = result[1] else: newtwayref.append(rtmap[ref]) for o in range(len(tway[REF])): if not (tway[REF][o] in newtwayref): nodedata.nodes[tway[REF][o]][ACTION] = DELETE tway[REF] = newtwayref tway[ACTION] = MODIFY
def main(): if len(sys.argv) != 3: return 0 segments = int(sys.argv[2]) pointlist = (sys.argv[1].split(';')) coordlist = [] for point in pointlist: coords = point.split(',') coordlist.append(projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857")) if len(coordlist) < 3: sys.stdout.write("<!--Too few control points-->") return 0 if segments == 0: # optimal number of segments for i in range(0, len(coordlist) - 2): P1 = coordlist[i] P2 = coordlist[i+1] P1P2 = (P2[0]-P1[0], P2[1]-P1[1]) P1P2abs = math.sqrt(P1P2[0]*P1P2[0] + P1P2[1]*P1P2[1]) segments += math.ceil(math.log(P1P2abs, 4)) # cat's magic formula segments=int(segments) tData = OsmData() wayid = tData.addway() step = 1.0 / segments for i in range(segments + 1): t = step * i node = projections.to4326(getpoint(coordlist, t), "EPSG:3857") nodeid = tData.addnode() tData.nodes[nodeid][LON] = node[0] tData.nodes[nodeid][LAT] = node[1] tData.ways[wayid][REF].append(nodeid) tData.addcomment("Done.") tData.write(sys.stdout) return 0
def calcpos(nodes, offset): coords = [None, None, None] if nodes[0] != None: coords[0] = projections.from4326((nodes[0][LON], nodes[0][LAT]), "EPSG:3857") coords[1] = projections.from4326((nodes[1][LON], nodes[1][LAT]), "EPSG:3857") if nodes[2] != None: coords[2] = projections.from4326((nodes[2][LON], nodes[2][LAT]), "EPSG:3857") if coords[0] == None: coords[0] = (2 * coords[1][0] - coords[2][0], 2 * coords[1][1] - coords[2][1]) v1 = normalize( (coords[2][1] - coords[1][1], coords[1][0] - coords[2][0])) v = (v1[0] * offset, v1[1] * offset) elif coords[2] == None: coords[2] = (2 * coords[1][0] - coords[0][0], 2 * coords[1][1] - coords[0][1]) v1 = normalize( (coords[1][1] - coords[0][1], coords[0][0] - coords[1][0])) v = (v1[0] * offset, v1[1] * offset) else: v1 = normalize( (coords[0][0] - coords[1][0], coords[0][1] - coords[1][1])) v2 = normalize( (coords[2][0] - coords[1][0], coords[2][1] - coords[1][1])) v1p2 = normalize((v1[0] + v2[0], v1[1] + v2[1])) soffset = offset * sign(v1[0] * v2[1] - v1[1] * v2[0]) v = (v1p2[0] * soffset, v1p2[1] * soffset) return projections.to4326((coords[1][0] + v[0], coords[1][1] + v[1]), "EPSG:3857")
def main(): if len(sys.argv) != 6: return 0 sides = int(sys.argv[5]) if sides < 3: return 0 coords = (sys.argv[1].split(',')) lon = float(coords[0].replace(',', '.')) lat = float(coords[1].replace(',', '.')) radius1 = float(sys.argv[2].replace(',', '.'))/math.cos(math.radians(lat)) radius2 = float(sys.argv[3].replace(',', '.'))/math.cos(math.radians(lat)) rot_angle = math.radians(float(sys.argv[4].replace(',', '.'))) if radius1 <= 0: return 0 if radius2 <= 0: return 0 startangle = 0 coords_m = projections.from4326((lon,lat), "EPSG:3857") tData = OsmData() wayid = tData.addway() for i in range(sides): angle = startangle + 2*math.pi*i/sides x = coords_m[0] + radius1 * math.cos(angle) * math.cos(rot_angle) - radius2 * math.sin(angle) * math.sin(rot_angle) y = coords_m[1] + radius1 * math.cos(angle) * math.sin(rot_angle) + radius2 * math.sin(angle) * math.cos(rot_angle) node = projections.to4326((x, y), "EPSG:3857") nodeid = tData.addnode() tData.nodes[nodeid][LON] = node[0] tData.nodes[nodeid][LAT] = node[1] tData.ways[wayid][REF].append(nodeid) tData.ways[wayid][REF].append(tData.ways[wayid][REF][0]) tData.addcomment("Done.") tData.write(sys.stdout) return 0
def main(): if len(sys.argv) != 3: return 0 coords = (sys.argv[1].split(',')) A = projections.from4326((float(coords[0]),float(coords[1])), "EPSG:3857") B = projections.from4326((float(coords[2]),float(coords[3])), "EPSG:3857") C = projections.from4326((float(coords[4]),float(coords[5])), "EPSG:3857") segments = int(sys.argv[2]) AM = ((B[0] - A[0])/2, (B[1] - A[1])/2) BN = ((C[0] - B[0])/2, (C[1] - B[1])/2) M = (A[0] + AM[0], A[1] + AM[1]) N = (B[0] + BN[0], B[1] + BN[1]) MM = (AM[1], -AM[0]) NN = (BN[1], -BN[0]) O = intersect(MM, M, NN, N) OA = (O[0] - A[0], O[1] - A[1]) r = math.sqrt(OA[0]*OA[0] + OA[1]*OA[1]) arc = createarc(O, A, C, r, segments) tData = OsmData() wayid = tData.addway() for point in arc: p = projections.to4326(point, "EPSG:3857") newid = tData.addnode() tData.nodes[newid][LON] = p[0] tData.nodes[newid][LAT] = p[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) tData.addcomment("Done.") tData.write(sys.stdout) #f = open("out.txt", "w") #tData.write(f) #f.close() return 0
def rectify(layer, point): corrfile = config.tiles_cache + layer.get("prefix", "") + "/rectify.txt" srs = layer["proj"] if not os.path.exists(corrfile): return point corr = open(corrfile, "r") lons, lats = point loni, lati, lona, lata = projections.projs[projections.proj_alias.get( srs, srs)]["bounds"] if (lons is loni and lats is lati) or (lons is lona and lats is lata): return point #print(pickle.dumps(coefs[layer]), file=sys.stderr) # sys.stderr.flush() lonaz, loniz, lataz, latiz = lona, loni, lata, lati maxdist = (1.80) for line in corr: d, c, b, a, user, ts = line.split() d, c, b, a = (float(d), float(c), float(b), float(a)) #for d,c,b,a in coefs[layer]: # print(a,b, distance(lons, lats, b, a), file=sys.stderr) if distance(b, a, lons, lats) < maxdist: if a > lats: if distance(a, b, lats, lons) <= distance( lata, lona, lats, lons): lata = a lataz = c if a < lats: if distance(a, b, lats, lons) <= distance( lati, loni, lats, lons): lati = a latiz = c if b > lons: if distance(a, b, lats, lons) <= distance( lata, lona, lats, lons): lona = b lonaz = d if b < lons: if distance(a, b, lats, lons) <= distance( lati, loni, lats, lons): loni = b loniz = d # print(loni, lati, lona, lata, distance(loni, lati, lona, lata), file=sys.stderr) # print("clat:", (lata-lati)/(lataz-latiz), (lona-loni)/(lonaz-loniz), file=sys.stderr) # sys.stderr.flush() lons, lats = projections.from4326(point, srs) lona, lata = projections.from4326((lona, lata), srs) loni, lati = projections.from4326((loni, lati), srs) lonaz, lataz = projections.from4326((lonaz, lataz), srs) loniz, latiz = projections.from4326((loniz, latiz), srs) latn = (lats - lati) / (lata - lati) latn = (latn * (lataz - latiz)) + latiz lonn = (lons - loni) / (lona - loni) lonn = (lonn * (lonaz - loniz)) + loniz return projections.to4326((lonn, latn), srs)
def __getattr__(self,name): if name=='x' or name=='y': self.x,self.y=projections.from4326((self.lon,self.lat),"EPSG:3857") return getattr(self,name) elif name=='lat' or name=='lon': self.lon,self.lat=projections.to4326((self.x,self.y),"EPSG:3857") return getattr(self,name) else: raise AttributeError('invalid Point attr "'+name+'"')
def r_bbox(layer, bbox): corrfile = config.tiles_cache + layer.get("prefix", "") + "/rectify.txt" srs = layer["proj"] if not os.path.exists(corrfile): return bbox a, b, c, d = projections.from4326(bbox, srs) cx, cy = (a + c) / 2, (b + d) / 2 cx1, cy1 = projections.from4326( rectify(layer, projections.to4326((cx, cy), srs)), srs) a1, b1 = projections.from4326( rectify(layer, projections.to4326((a, b), srs)), srs) c1, d1 = projections.from4326( rectify(layer, projections.to4326((c, d), srs)), srs) dx, dy = ((cx1 - cx) + (a1 - a) + (c1 - c)) / 3, ((cy1 - cy) + (b1 - b) + (d1 - d)) / 3 # print(dx,dy, file=sys.stderr) # sys.stderr.flush() return projections.to4326((a + dx, b + dy, c + dx, d + dy), srs)
def rectify(layer, point): corrfile = config.tiles_cache + layer.get("prefix", "")+ "/rectify.txt" srs = layer["proj"] if not os.path.exists(corrfile): return point corr = open(corrfile, "r") lons, lats = point loni, lati, lona, lata = projections.projs[projections.proj_alias.get(srs,srs)]["bounds"] if (lons is loni and lats is lati) or (lons is lona and lats is lata): return point #print >> sys.stderr, pickle.dumps(coefs[layer]) # sys.stderr.flush() lonaz, loniz, lataz, latiz = lona, loni, lata, lati maxdist = (1.80) for line in corr: d,c,b,a,user,ts = line.split() d,c,b,a = (float(d),float(c),float(b),float(a)) #for d,c,b,a in coefs[layer]: # print >> sys.stderr, a,b, distance(lons, lats, b, a) if distance(b,a, lons, lats) < maxdist: if a > lats: if distance(a,b,lats,lons) <= distance(lata,lona,lats,lons): lata = a lataz = c if a < lats: if distance(a,b,lats,lons) <= distance(lati,loni,lats,lons): lati = a latiz = c if b > lons: if distance(a,b,lats,lons) <= distance(lata,lona,lats,lons): lona = b lonaz = d if b < lons: if distance(a,b,lats,lons) <= distance(lati,loni,lats,lons): loni = b loniz = d # print >> sys.stderr, loni, lati, lona, lata, distance(loni, lati, lona, lata) # print >> sys.stderr, "clat:", (lata-lati)/(lataz-latiz), (lona-loni)/(lonaz-loniz) # sys.stderr.flush() lons, lats = projections.from4326(point, srs) lona, lata = projections.from4326((lona,lata), srs) loni, lati = projections.from4326((loni,lati), srs) lonaz, lataz = projections.from4326((lonaz,lataz), srs) loniz, latiz = projections.from4326((loniz,latiz), srs) latn = (lats-lati)/(lata-lati) latn = (latn * (lataz-latiz))+latiz lonn = (lons-loni)/(lona-loni) lonn = (lonn * (lonaz-loniz))+loniz return projections.to4326((lonn,latn), srs)
def createcell(b_cells, rData, nData): n = 0 for i in b_cells: wayid = rData.addway() for y in i: node = projections.to4326((y[0], y[1]), "EPSG:3857") nodeid = rData.addnode() rData.nodes[nodeid][LON] = node[0] rData.nodes[nodeid][LAT] = node[1] rData.ways[wayid][REF].append(nodeid) rData.ways[wayid][REF].append(rData.ways[wayid][REF][0]) n += 1 rData.addcomment("Created " + str(n) + " squares.") rData.write(sys.stdout) return 0
def createcell(b_cells, rData, nData): n=0 for i in b_cells: wayid = rData.addway() for y in i: node = projections.to4326((y[0], y[1]), "EPSG:3857") nodeid = rData.addnode() rData.nodes[nodeid][LON] = node[0] rData.nodes[nodeid][LAT] = node[1] rData.ways[wayid][REF].append(nodeid) rData.ways[wayid][REF].append(rData.ways[wayid][REF][0]) n+=1 rData.addcomment("Created " + str(n) + " squares.") rData.write(sys.stdout) return 0
def treplace(nodedata, rdata, rwayid, tdata, twayid, reference, target): rway = rdata.ways[rwayid] tway = tdata.ways[twayid] newtwayref = [] rtmap = {} for i, ref in enumerate(rway[REF]): if rtmap.get(ref) == None: if i < len(tway[REF]) - 1: node = nodedata.nodes[tway[REF][i]] node[ACTION] = MODIFY newtwayref.append(tway[REF][i]) rtmap[ref] = tway[REF][i] else: nodeid = nodedata.addnode() node = nodedata.nodes[nodeid] newtwayref.append(nodeid) rtmap[ref] = nodeid angle = math.radians(reference[0] - target[0]) mrefnode = projections.from4326( (nodedata.nodes[ref][LON], nodedata.nodes[ref][LAT]), "EPSG:3857") mreference = projections.from4326( (reference[1][0], reference[1][1]), "EPSG:3857") maboutnull = (mrefnode[0] - mreference[0], mrefnode[1] - mreference[1]) mrotated = (maboutnull[0] * math.cos(angle) - maboutnull[1] * math.sin(angle), maboutnull[0] * math.sin(angle) + maboutnull[1] * math.cos(angle)) mtarget = projections.from4326(target[1], "EPSG:3857") result = projections.to4326( (mtarget[0] + mrotated[0], mtarget[1] + mrotated[1]), "EPSG:3857") node[LON] = result[0] node[LAT] = result[1] else: newtwayref.append(rtmap[ref]) for o in range(len(tway[REF])): if not (tway[REF][o] in newtwayref): nodedata.nodes[tway[REF][o]][ACTION] = DELETE tway[REF] = newtwayref tway[ACTION] = MODIFY
def calcpos(nodes, offset): coords = [None, None, None] if nodes[0] != None: coords[0] = projections.from4326((nodes[0][LON],nodes[0][LAT]), "EPSG:3857") coords[1] = projections.from4326((nodes[1][LON],nodes[1][LAT]), "EPSG:3857") if nodes[2] != None: coords[2] = projections.from4326((nodes[2][LON],nodes[2][LAT]), "EPSG:3857") if coords[0] == None: coords[0] = (2*coords[1][0] - coords[2][0], 2*coords[1][1] - coords[2][1]) v1 = normalize((coords[2][1] - coords[1][1], coords[1][0] - coords[2][0])) v = (v1[0] * offset, v1[1] * offset) elif coords[2] == None: coords[2] = (2*coords[1][0] - coords[0][0], 2*coords[1][1] - coords[0][1]) v1 = normalize((coords[1][1] - coords[0][1], coords[0][0] - coords[1][0])) v = (v1[0] * offset, v1[1] * offset) else: v1 = normalize((coords[0][0] - coords[1][0], coords[0][1] - coords[1][1])) v2 = normalize((coords[2][0] - coords[1][0], coords[2][1] - coords[1][1])) v1p2 = normalize((v1[0] + v2[0], v1[1] + v2[1])) soffset = offset * sign(v1[0]*v2[1] - v1[1]*v2[0]) v = (v1p2[0] * soffset, v1p2[1] * soffset) return projections.to4326((coords[1][0] + v[0], coords[1][1] + v[1]), "EPSG:3857")
def main(): if len(sys.argv) != 3: return 0 segments = int(sys.argv[2]) pointlist = (sys.argv[1].split(';')) coordlist = [] for point in pointlist: coords = point.split(',') coordlist.append(projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857")) if len(coordlist) < 4: sys.stdout.write("<!--Too few control points-->") return 0 if segments < 0: sys.stdout.write("<!--Segments must be greater than zero-->"); tData = OsmData() wayid = tData.addway() step = 1.0 / segments for j in range (1, len(coordlist)-2): # for segments other than the first, skip the first point since it's the # last point of the previous segment - otherwise you'll get overlapping points # at the segment ends. if j > 1: segs = range(1,segments+1) else: segs = range(segments+1) for i in segs: t = step * i node = projections.to4326(spline_4p(t, coordlist[j-1], coordlist[j], coordlist[j+1], coordlist[j+2]), "EPSG:3857") nodeid = tData.addnode() tData.nodes[nodeid][LON] = node[0] tData.nodes[nodeid][LAT] = node[1] tData.ways[wayid][REF].append(nodeid) tData.addcomment("Done.") tData.write(sys.stdout) return 0
def twms_main(data): """ Do main TWMS work. data - dictionary of params. returns (error_code, content_type, resp) """ start_time = datetime.datetime.now() content_type = "text/html" resp = "" srs = data.get("srs", "EPSG:4326") gpx = data.get("gpx", "").split(",") if gpx == ['']: gpx = [] wkt = data.get("wkt", "") trackblend = float(data.get("trackblend", "0.5")) color = data.get("color", data.get("colour", "")).split(",") track = False tracks = [] if len(gpx) == 0: req_bbox = projections.from4326( (27.6518898, 53.8683186, 27.6581944, 53.8720359), srs) else: for g in gpx: local_gpx = config.gpx_cache + "%s.gpx" % g if not os.path.exists(config.gpx_cache): os.makedirs(config.gpx_cache) if not os.path.exists(local_gpx): urllib.urlretrieve( "http://www.openstreetmap.org/trace/%s/data" % g, local_gpx) if not track: track = GPXParser(local_gpx) req_bbox = projections.from4326(track.bbox, srs) else: track = GPXParser(local_gpx) req_bbox = bbox.add(req_bbox, projections.from4326(track.bbox, srs)) tracks.append(track) req_type = data.get("request", "GetMap") version = data.get("version", "1.1.1") ref = data.get("ref", config.service_url) if req_type == "GetCapabilities": content_type, resp = capabilities.get(version, ref) return (OK, content_type, resp) layer = data.get("layers", config.default_layers).split(",") if ("layers" in data) and not layer[0]: layer = ["transparent"] if req_type == "GetCorrections": points = data.get("points", data.get("POINTS", "")).split("=") resp = "" points = [a.split(",") for a in points] points = [(float(a[0]), float(a[1])) for a in points] req.content_type = "text/plain" for lay in layer: for point in points: resp += "%s,%s;" % tuple( correctify.rectify(config.layers[lay], point)) resp += "\n" return (OK, content_type, resp) force = data.get("force", "") if force != "": force = force.split(",") force = tuple(force) filt = data.get("filt", "") if filt != "": filt = filt.split(",") filt = tuple(filt) if layer == [""]: content_type = "text/html" resp = overview.html(ref) return (OK, content_type, resp) format = data.get("format", config.default_format).lower() format = formats.get("image/" + format, format) format = formats.get(format, format) if format not in formats.values(): return (ERROR, content_type, "Invalid format") content_type = mimetypes[format] width = 0 height = 0 resp_cache_path, resp_ext = "", "" if req_type == "GetTile": width = 256 height = 256 height = int(data.get("height", height)) width = int(data.get("width", width)) srs = data.get("srs", "EPSG:3857") x = int(data.get("x", 0)) y = int(data.get("y", 0)) z = int(data.get("z", 1)) + 1 if "cache_tile_responses" in dir(config) and not wkt and (len(gpx) == 0): if (srs, tuple(layer), filt, width, height, force, format) in config.cache_tile_responses: resp_cache_path, resp_ext = config.cache_tile_responses[( srs, tuple(layer), filt, width, height, force, format)] resp_cache_path = resp_cache_path + "/%s/%s/%s.%s" % ( z - 1, x, y, resp_ext) if os.path.exists(resp_cache_path): return (OK, content_type, open(resp_cache_path, "r").read()) if len(layer) == 1: if layer[0] in config.layers: if config.layers[layer[0]][ "proj"] == srs and width is 256 and height is 256 and not filt and not force and not correctify.has_corrections( config.layers[layer[0]]): local = config.tiles_cache + config.layers[ layer[0]]["prefix"] + "/z%s/%s/x%s/%s/y%s." % ( z, x / 1024, x, y / 1024, y) ext = config.layers[layer]["ext"] adds = ["", "ups."] for add in adds: if os.path.exists(local + add + ext): tile_file = open(local + add + ext, "r") resp = tile_file.read() return (OK, content_type, resp) req_bbox = projections.from4326(projections.bbox_by_tile(z, x, y, srs), srs) if data.get("bbox", None): req_bbox = tuple(map(float, data.get("bbox", req_bbox).split(","))) req_bbox = projections.to4326(req_bbox, srs) req_bbox, flip_h = bbox.normalize(req_bbox) box = req_bbox #print(req_bbox, file=sys.stderr) #sys.stderr.flush() height = int(data.get("height", height)) width = int(data.get("width", width)) width = min(width, config.max_width) height = min(height, config.max_height) if (width == 0) and (height == 0): width = 350 # layer = layer.split(",") imgs = 1. ll = layer.pop(0) if ll[-2:] == "!c": ll = ll[:-2] if wkt: wkt = "," + wkt wkt = correctify.corr_wkt(config.layers[ll]) + wkt srs = config.layers[ll]["proj"] try: result_img = getimg(box, srs, (height, width), config.layers[ll], start_time, force) except KeyError: result_img = Image.new("RGBA", (width, height)) #width, height = result_img.size for ll in layer: if ll[-2:] == "!c": ll = ll[:-2] if wkt: wkt = "," + wkt wkt = correctify.corr_wkt(config.layers[ll]) + wkt srs = config.layers[ll]["proj"] im2 = getimg(box, srs, (height, width), config.layers[ll], start_time, force) if "empty_color" in config.layers[ll]: ec = ImageColor.getcolor(config.layers[ll]["empty_color"], "RGBA") sec = set(ec) if "empty_color_delta" in config.layers[ll]: delta = config.layers[ll]["empty_color_delta"] for tr in range(-delta, delta): for tg in range(-delta, delta): for tb in range(-delta, delta): if (ec[0] + tr) >= 0 and (ec[0] + tr) < 256 and ( ec[1] + tr ) >= 0 and (ec[1] + tr) < 256 and ( ec[2] + tr) >= 0 and (ec[2] + tr) < 256: sec.add((ec[0] + tr, ec[1] + tg, ec[2] + tb, ec[3])) i2l = im2.load() for x in range(0, im2.size[0]): for y in range(0, im2.size[1]): t = i2l[x, y] if t in sec: i2l[x, y] = (t[0], t[1], t[2], 0) if not im2.size == result_img.size: im2 = im2.resize(result_img.size, Image.ANTIALIAS) im2 = Image.composite(im2, result_img, im2.split()[3]) # imgs/(imgs+1.)) if "noblend" in force: result_img = im2 else: result_img = Image.blend(im2, result_img, 0.5) imgs += 1. ##Applying filters result_img = filter.raster(result_img, filt, req_bbox, srs) #print(wkt, file=sys.stderr) #sys.stderr.flush() if wkt: result_img = drawing.wkt(wkt, result_img, req_bbox, srs, color if len(color) > 0 else None, trackblend) if len(gpx) > 0: last_color = None c = iter(color) for track in tracks: try: last_color = c.next() except StopIteration: pass result_img = drawing.gpx(track, result_img, req_bbox, srs, last_color, trackblend) if flip_h: result_img = ImageOps.flip(result_img) image_content = BytesIO() if format == "JPEG": try: result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) except IOError: result_img.save(image_content, format, quality=config.output_quality) elif format == "PNG": result_img.save(image_content, format, progressive=config.output_progressive, optimize=config.output_optimize) elif format == "GIF": result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) else: ## workaround for GIF result_img = result_img.convert("RGB") result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) resp = image_content.getvalue() if resp_cache_path: try: "trying to create local cache directory, if it doesn't exist" os.makedirs("/".join(resp_cache_path.split("/")[:-1])) except OSError: pass try: a = open(resp_cache_path, "w") a.write(resp) a.close() except (OSError, IOError): print("error saving response answer to file %s." % (resp_cache_path), file=sys.stderr) sys.stderr.flush() return (OK, content_type, resp)
def main(): if len(sys.argv) != 3: return 0 wData = OsmData() # Way nData = OsmData() # Nodes wData.read(sys.stdin) wData.read(sys.stdin) nData.read(sys.stdin) radius = float(sys.argv[1]) segments = int(sys.argv[2]) nodes = [] usednodes = set() for way in wData.ways.items(): for key in nData.nodes.keys(): if key in usednodes: continue try: index = way[1][REF].index(key) except ValueError: pass else: lastindex = len(way[1][REF]) - 1 if way[1][REF][0] == way[1][REF][lastindex]: # polygon if index == 0: nodes.append([ way[1][REF][lastindex - 1], key, way[1][REF][index + 1], way[0], index ]) # previous node, node for fillet, next node, way usednodes.add(key) else: nodes.append([ way[1][REF][index - 1], key, way[1][REF][index + 1], way[0], index ]) usednodes.add(key) else: # way if index > 0 and index < lastindex: nodes.append([ way[1][REF][index - 1], key, way[1][REF][index + 1], way[0], index ]) usednodes.add(key) tData = OsmData() tData.mergedata(nData) tData.mergedata(wData) for pack in nodes: M = projections.from4326( (wData.nodes[pack[0]][LON], wData.nodes[pack[0]][LAT]), "EPSG:3857") # previous node O = projections.from4326( (wData.nodes[pack[1]][LON], wData.nodes[pack[1]][LAT]), "EPSG:3857") # center node N = projections.from4326( (wData.nodes[pack[2]][LON], wData.nodes[pack[2]][LAT]), "EPSG:3857") # next node r = radius / math.cos(math.radians(wData.nodes[pack[1]][LAT])) OM = (M[0] - O[0], M[1] - O[1]) ON = (N[0] - O[0], N[1] - O[1]) OMabs = math.sqrt(OM[0] * OM[0] + OM[1] * OM[1]) ONabs = math.sqrt(ON[0] * ON[0] + ON[1] * ON[1]) cosa = (OM[0] * ON[0] + OM[1] * ON[1]) / (OMabs * ONabs) OCabs = r / (math.sqrt((1 - cosa) / 2)) OMnorm = (OM[0] / OMabs, OM[1] / OMabs) ONnorm = (ON[0] / ONabs, ON[1] / ONabs) bisectrix = (OMnorm[0] + ONnorm[0], OMnorm[1] + ONnorm[1]) bisectrixabs = math.sqrt(bisectrix[0] * bisectrix[0] + bisectrix[1] * bisectrix[1]) bisectrixnorm = (bisectrix[0] / bisectrixabs, bisectrix[1] / bisectrixabs) OC = (bisectrixnorm[0] * OCabs, bisectrixnorm[1] * OCabs) C = (O[0] + OC[0], O[1] + OC[1]) P1 = project(OM, O, C) P2 = project(ON, O, C) arc = createarc(C, P1, P2, r, segments) arcref = [] exists = int(segments / 2) for point in range(len(arc)): p = projections.to4326(arc[point], "EPSG:3857") if point == exists: tData.nodes[pack[1]][ACTION] = MODIFY tData.nodes[pack[1]][LON] = p[0] tData.nodes[pack[1]][LAT] = p[1] arcref.append(pack[1]) else: newid = tData.addnode() tData.nodes[newid][LON] = p[0] tData.nodes[newid][LAT] = p[1] tData.nodes[newid][TAG] = {} arcref.append(newid) way = tData.ways[pack[3]] way[ACTION] = MODIFY lastindex = len(way[REF]) - 1 index = way[REF].index(pack[1]) ref = way[REF][:] if way[REF][0] == way[REF][lastindex] and index == 0: # polygon way[REF] = arcref[:] way[REF] += (ref[1:lastindex]) way[REF] += [(arcref[0])] else: # way way[REF] = ref[:index] + arcref + ref[index + 1:] tData.ways[pack[3]] = way tData.addcomment("Done.") tData.write(sys.stdout) #f = open("out.txt", "w") #tData.write(f) #f.close() return 0
def main(): if len(sys.argv) != 4: return 0 coords = (sys.argv[1].split(',')) A = projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857") B = projections.from4326((float(coords[2]), float(coords[3])), "EPSG:3857") C = projections.from4326((float(coords[4]), float(coords[5])), "EPSG:3857") segments = int(sys.argv[2]) params = int(sys.argv[3]) AM = ((B[0] - A[0]) / 2, (B[1] - A[1]) / 2) BN = ((C[0] - B[0]) / 2, (C[1] - B[1]) / 2) M = (A[0] + AM[0], A[1] + AM[1]) N = (B[0] + BN[0], B[1] + BN[1]) MM = (AM[1], -AM[0]) NN = (BN[1], -BN[0]) O = intersect(MM, M, NN, N) # circle center OA = (O[0] - A[0], O[1] - A[1]) r = math.sqrt(OA[0] * OA[0] + OA[1] * OA[1]) # radius arc = createarc(O, A, C, r, segments) tData = OsmData() wayid = tData.addway() for point in arc: p = projections.to4326(point, "EPSG:3857") newid = tData.addnode() tData.nodes[newid][LON] = p[0] tData.nodes[newid][LAT] = p[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) if params == 1: p2 = projections.to4326(O, "EPSG:3857") # center p1 = projections.to4326((O[0] - r * 1.05, O[1]), "EPSG:3857") # axes points p3 = projections.to4326((O[0] + r * 1.05, O[1]), "EPSG:3857") p4 = projections.to4326((O[0], O[1] - r * 1.05), "EPSG:3857") p5 = projections.to4326((O[0], O[1] + r * 1.05), "EPSG:3857") wayid = tData.addway() newid = tData.addnode() tData.nodes[newid][LON] = p1[0] tData.nodes[newid][LAT] = p1[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) newid2 = tData.addnode() tData.nodes[newid2][LON] = p2[0] tData.nodes[newid2][LAT] = p2[1] tData.nodes[newid2][TAG] = {} tData.ways[wayid][REF].append(newid2) newid = tData.addnode() tData.nodes[newid][LON] = p3[0] tData.nodes[newid][LAT] = p3[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) wayid = tData.addway() newid = tData.addnode() tData.nodes[newid][LON] = p4[0] tData.nodes[newid][LAT] = p4[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) tData.ways[wayid][REF].append(newid2) newid = tData.addnode() tData.nodes[newid][LON] = p5[0] tData.nodes[newid][LAT] = p5[1] tData.nodes[newid][TAG] = {} tData.ways[wayid][REF].append(newid) tData.addcomment("Done.") tData.write(sys.stdout) #f = open("out.txt", "w") #tData.write(f) #f.close() return 0
def main(): if len(sys.argv) != 3: return 0 wData = OsmData() # Way nData = OsmData() # Nodes wData.read(sys.stdin) wData.read(sys.stdin) nData.read(sys.stdin) radius = float(sys.argv[1]) segments = int(sys.argv[2]) nodes = [] usednodes = set() for way in wData.ways.items(): for key in nData.nodes.keys(): if key in usednodes: continue try: index = way[1][REF].index(key) except ValueError: pass else: lastindex = len(way[1][REF]) - 1 if way[1][REF][0] == way[1][REF][lastindex]: # polygon if index == 0: nodes.append([way[1][REF][lastindex-1], key, way[1][REF][index+1], way[0], index]) # previous node, node for fillet, next node, way usednodes.add(key) else: nodes.append([way[1][REF][index-1], key, way[1][REF][index+1], way[0], index]) usednodes.add(key) else: # way if index > 0 and index < lastindex: nodes.append([way[1][REF][index-1], key, way[1][REF][index+1], way[0], index]) usednodes.add(key) tData = OsmData() tData.mergedata(nData) tData.mergedata(wData) for pack in nodes: M = projections.from4326( (wData.nodes[pack[0]][LON], wData.nodes[pack[0]][LAT]), "EPSG:3857") # previous node O = projections.from4326( (wData.nodes[pack[1]][LON], wData.nodes[pack[1]][LAT]), "EPSG:3857") # center node N = projections.from4326( (wData.nodes[pack[2]][LON], wData.nodes[pack[2]][LAT]), "EPSG:3857") # next node r = radius / math.cos(math.radians(wData.nodes[pack[1]][LAT])) OM = (M[0] - O[0], M[1] - O[1]) ON = (N[0] - O[0], N[1] - O[1]) OMabs = math.sqrt(OM[0]*OM[0] + OM[1]*OM[1]) ONabs = math.sqrt(ON[0]*ON[0] + ON[1]*ON[1]) cosa = (OM[0]*ON[0] + OM[1]*ON[1]) / (OMabs * ONabs) OCabs = r / (math.sqrt((1 - cosa) / 2)) OMnorm = (OM[0]/OMabs, OM[1]/OMabs) ONnorm = (ON[0]/ONabs, ON[1]/ONabs) bisectrix = (OMnorm[0] + ONnorm[0], OMnorm[1] + ONnorm[1]) bisectrixabs = math.sqrt(bisectrix[0]*bisectrix[0] + bisectrix[1]*bisectrix[1]) bisectrixnorm = (bisectrix[0]/bisectrixabs, bisectrix[1]/bisectrixabs) OC = (bisectrixnorm[0]*OCabs, bisectrixnorm[1]*OCabs) C = (O[0]+OC[0], O[1]+OC[1]) P1 = project(OM, O, C) P2 = project(ON, O, C) arc = createarc(C, P1, P2, r, segments) arcref = [] exists = int(segments/2) for point in range(len(arc)): p = projections.to4326(arc[point], "EPSG:3857") if point == exists: tData.nodes[pack[1]][ACTION] = MODIFY tData.nodes[pack[1]][LON] = p[0] tData.nodes[pack[1]][LAT] = p[1] arcref.append(pack[1]) else: newid = tData.addnode() tData.nodes[newid][LON] = p[0] tData.nodes[newid][LAT] = p[1] tData.nodes[newid][TAG] = {} arcref.append(newid) way = tData.ways[pack[3]] way[ACTION] = MODIFY lastindex = len(way[REF]) - 1 index = way[REF].index(pack[1]) ref = way[REF][:] if way[REF][0] == way[REF][lastindex] and index == 0: # polygon way[REF] = arcref[:] way[REF] += (ref[1:lastindex]) way[REF] += [(arcref[0])] else: # way way[REF] = ref[:index] + arcref + ref[index+1:] tData.ways[pack[3]] = way tData.addcomment("Done.") tData.write(sys.stdout) #f = open("out.txt", "w") #tData.write(f) #f.close() return 0
def main(): if len(sys.argv) != 4: return 0 rData = OsmData() # References mData = OsmData() # Objects for moving rData.read(sys.stdin) mData.read(sys.stdin) coords = (sys.argv[1].split(',')) p1 = projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857") coords = (sys.argv[2].split(',')) p2 = projections.from4326((float(coords[0]), float(coords[1])), "EPSG:3857") if sys.argv[3] == "Yes": nData = OsmData() # New objects nMap = Map() wMap = Map() rMap = Map() for key in rData.nodes.keys(): p = projections.from4326( (rData.nodes[key][LON], rData.nodes[key][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") nData.nodes[nMap[key]] = {} nData.nodes[nMap[key]][TAG] = rData.nodes[key][TAG] nData.nodes[nMap[key]][LON] = p[0] nData.nodes[nMap[key]][LAT] = p[1] nData.nodes[nMap[key]][ACTION] = CREATE for key in mData.nodes.keys(): p = projections.from4326( (mData.nodes[key][LON], mData.nodes[key][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") nData.nodes[nMap[key]] = {} nData.nodes[nMap[key]][TAG] = mData.nodes[key][TAG] nData.nodes[nMap[key]][LON] = p[0] nData.nodes[nMap[key]][LAT] = p[1] nData.nodes[nMap[key]][ACTION] = CREATE for key in rData.ways.keys(): nData.ways[wMap[key]] = {} nData.ways[wMap[key]][TAG] = rData.ways[key][TAG] nData.ways[wMap[key]][REF] = [] for nd in rData.ways[key][REF]: nData.ways[wMap[key]][REF].append(nMap[nd]) nData.ways[wMap[key]][ACTION] = CREATE for key in mData.ways.keys(): nData.ways[wMap[key]] = {} nData.ways[wMap[key]][TAG] = mData.ways[key][TAG] nData.ways[wMap[key]][REF] = [] for nd in mData.ways[key][REF]: nData.ways[wMap[key]][REF].append(nMap[nd]) nData.ways[wMap[key]][ACTION] = CREATE for key in rData.relations.keys(): nData.relations[rMap[key]] = {} nData.relations[rMap[key]][TAG] = rData.relations[key][TAG] nData.relations[rMap[key]][REF] = [[], [], []] for nd in rData.relations[key][REF][NODES]: if nData.nodes.get(nMap[nd]) != None: nData.relations[rMap[key]][REF][NODES].append( (nMap[nd[0]], nd[1])) for way in rData.relations[key][REF][WAYS]: if nData.ways.get(wMap[way]) != None: nData.relations[rMap[key]][REF][WAYS].append( (wMap[way[0]], way[1])) for relation in rData.relations[key][REF][RELATIONS]: if rData.relations.get( relation) != None or mData.relations.get( relation) != None: nData.relations[rMap[key]][REF][RELATIONS].append( (rMap[relation[0]], relation[1])) nData.relations[rMap[key]][ACTION] = CREATE for key in mData.relations.keys(): nData.relations[rMap[key]] = {} nData.relations[rMap[key]][TAG] = mData.relations[key][TAG] nData.relations[rMap[key]][REF] = [[], [], []] for nd in mData.relations[key][REF][NODES]: if nData.nodes.get(nMap[nd[0]]) != None: nData.relations[rMap[key]][REF][NODES].append( (nMap[nd[0]], nd[1])) for way in mData.relations[key][REF][WAYS]: if nData.ways.get(wMap[way[0]]) != None: nData.relations[rMap[key]][REF][WAYS].append( (wMap[way[0]], way[1])) for relation in mData.relations[key][REF][RELATIONS]: if rData.relations.get( relation[0]) != None or mData.relations.get( relation) != None: nData.relations[rMap[key]][REF][RELATIONS].append( (rMap[relation[0]], relation[1])) nData.relations[rMap[key]][ACTION] = CREATE nData.addcomment("Done.") nData.write(sys.stdout) elif sys.argv[3] == "No": rData.nodes.update(mData.nodes) for nkey in rData.nodes.keys(): p = projections.from4326( (rData.nodes[nkey][LON], rData.nodes[nkey][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") rData.nodes[nkey][LON] = p[0] rData.nodes[nkey][LAT] = p[1] rData.nodes[nkey][ACTION] = MODIFY rData.write(sys.stdout) return 0
def main(): if len(sys.argv) != 4: return 0 rData = OsmData() # References mData = OsmData() # Objects for moving rData.read(sys.stdin) mData.read(sys.stdin) coords = (sys.argv[1].split(',')) p1 = projections.from4326((float(coords[0]),float(coords[1])), "EPSG:3857") coords = (sys.argv[2].split(',')) p2 = projections.from4326((float(coords[0]),float(coords[1])), "EPSG:3857") if sys.argv[3] == "Yes": nData = OsmData() # New objects nMap = Map() wMap = Map() rMap = Map() for key in rData.nodes.keys(): p = projections.from4326((rData.nodes[key][LON],rData.nodes[key][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") nData.nodes[nMap[key]] = {} nData.nodes[nMap[key]][TAG] = rData.nodes[key][TAG] nData.nodes[nMap[key]][LON] = p[0] nData.nodes[nMap[key]][LAT] = p[1] nData.nodes[nMap[key]][ACTION] = CREATE for key in mData.nodes.keys(): p = projections.from4326((mData.nodes[key][LON],mData.nodes[key][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") nData.nodes[nMap[key]] = {} nData.nodes[nMap[key]][TAG] = mData.nodes[key][TAG] nData.nodes[nMap[key]][LON] = p[0] nData.nodes[nMap[key]][LAT] = p[1] nData.nodes[nMap[key]][ACTION] = CREATE for key in rData.ways.keys(): nData.ways[wMap[key]] = {} nData.ways[wMap[key]][TAG] = rData.ways[key][TAG] nData.ways[wMap[key]][REF] = [] for nd in rData.ways[key][REF]: nData.ways[wMap[key]][REF].append(nMap[nd]) nData.ways[wMap[key]][ACTION] = CREATE for key in mData.ways.keys(): nData.ways[wMap[key]] = {} nData.ways[wMap[key]][TAG] = mData.ways[key][TAG] nData.ways[wMap[key]][REF] = [] for nd in mData.ways[key][REF]: nData.ways[wMap[key]][REF].append(nMap[nd]) nData.ways[wMap[key]][ACTION] = CREATE for key in rData.relations.keys(): nData.relations[rMap[key]] = {} nData.relations[rMap[key]][TAG] = rData.relations[key][TAG] nData.relations[rMap[key]][REF] = [[], [], []] for nd in rData.relations[key][REF][NODES]: if nData.nodes.get(nMap[nd]) != None: nData.relations[rMap[key]][REF][NODES].append((nMap[nd[0]], nd[1])) for way in rData.relations[key][REF][WAYS]: if nData.ways.get(wMap[way]) != None: nData.relations[rMap[key]][REF][WAYS].append((wMap[way[0]], way[1])) for relation in rData.relations[key][REF][RELATIONS]: if rData.relations.get(relation) != None or mData.relations.get(relation) != None: nData.relations[rMap[key]][REF][RELATIONS].append((rMap[relation[0]], relation[1])) nData.relations[rMap[key]][ACTION] = CREATE for key in mData.relations.keys(): nData.relations[rMap[key]] = {} nData.relations[rMap[key]][TAG] = mData.relations[key][TAG] nData.relations[rMap[key]][REF] = [[], [], []] for nd in mData.relations[key][REF][NODES]: if nData.nodes.get(nMap[nd[0]]) != None: nData.relations[rMap[key]][REF][NODES].append((nMap[nd[0]], nd[1])) for way in mData.relations[key][REF][WAYS]: if nData.ways.get(wMap[way[0]]) != None: nData.relations[rMap[key]][REF][WAYS].append((wMap[way[0]], way[1])) for relation in mData.relations[key][REF][RELATIONS]: if rData.relations.get(relation[0]) != None or mData.relations.get(relation) != None: nData.relations[rMap[key]][REF][RELATIONS].append((rMap[relation[0]], relation[1])) nData.relations[rMap[key]][ACTION] = CREATE nData.addcomment("Done.") nData.write(sys.stdout) elif sys.argv[3] == "No": rData.nodes.update(mData.nodes) for nkey in rData.nodes.keys(): p = projections.from4326((rData.nodes[nkey][LON],rData.nodes[nkey][LAT]), "EPSG:3857") p = mirror(p, p1, p2) p = projections.to4326(p, "EPSG:3857") rData.nodes[nkey][LON] = p[0] rData.nodes[nkey][LAT] = p[1] rData.nodes[nkey][ACTION] = MODIFY rData.write(sys.stdout) return 0
def getimg(bbox, request_proj, size, layer, start_time, force): orig_bbox = bbox ## Making 4-corner maximal bbox bbox_p = projections.from4326(bbox, request_proj) bbox_p = projections.to4326((bbox_p[2], bbox_p[1], bbox_p[0], bbox_p[3]), request_proj) bbox_4 = ((bbox_p[2], bbox_p[3]), (bbox[0], bbox[1]), (bbox_p[0], bbox_p[1]), (bbox[2], bbox[3])) if "nocorrect" not in force: bb4 = [] for point in bbox_4: bb4.append(correctify.rectify(layer, point)) bbox_4 = bb4 bbox = bbox_utils.expand_to_point(bbox, bbox_4) #print(bbox) #print(orig_bbox) global cached_objs H, W = size max_zoom = layer.get("max_zoom", config.default_max_zoom) min_zoom = layer.get("min_zoom", 1) zoom = bbox_utils.zoom_for_bbox(bbox, size, layer, min_zoom, max_zoom, (config.max_height, config.max_width)) lo1, la1, lo2, la2 = bbox from_tile_x, from_tile_y, to_tile_x, to_tile_y = projections.tile_by_bbox( bbox, zoom, layer["proj"]) cut_from_x = int(256 * (from_tile_x - int(from_tile_x))) cut_from_y = int(256 * (from_tile_y - int(from_tile_y))) cut_to_x = int(256 * (to_tile_x - int(to_tile_x))) cut_to_y = int(256 * (to_tile_y - int(to_tile_y))) from_tile_x, from_tile_y = int(from_tile_x), int(from_tile_y) to_tile_x, to_tile_y = int(to_tile_x), int(to_tile_y) bbox_im = (cut_from_x, cut_to_y, 256 * (to_tile_x - from_tile_x) + cut_to_x, 256 * (from_tile_y - to_tile_y) + cut_from_y) x = 256 * (to_tile_x - from_tile_x + 1) y = 256 * (from_tile_y - to_tile_y + 1) #print(x, y, file=sys.stderr) #sys.stderr.flush() out = Image.new("RGBA", (x, y)) for x in range(from_tile_x, to_tile_x + 1): for y in range(to_tile_y, from_tile_y + 1): got_image = False im1 = tile_image(layer, zoom, x, y, start_time, real=True) if im1: if "prefix" in layer: if (layer["prefix"], zoom, x, y) not in cached_objs: if im1.is_ok: cached_objs[(layer["prefix"], zoom, x, y)] = im1 cached_hist_list.append( (layer["prefix"], zoom, x, y)) #print((layer["prefix"], zoom, x, y), cached_objs[(layer["prefix"], zoom, x, y)], file=sys.stderr) #sys.stderr.flush() if len(cached_objs) >= config.max_ram_cached_tiles: del cached_objs[cached_hist_list.pop(0)] #print("Removed tile from cache", file=sys.stderr) #sys.stderr.flush() else: ec = ImageColor.getcolor( layer.get("empty_color", config.default_background), "RGBA") #ec = (ec[0],ec[1],ec[2],0) im1 = Image.new("RGBA", (256, 256), ec) out.paste(im1, ( (x - from_tile_x) * 256, (-to_tile_y + y) * 256, )) if "filter" in layer: out = filter.raster(out, layer["filter"], orig_bbox, request_proj) ## TODO: Here's a room for improvement. we could drop this crop in case user doesn't need it. out = out.crop(bbox_im) if "noresize" not in force: if (H == W) and (H == 0): W, H = out.size if H == 0: H = out.size[1] * W // out.size[0] if W == 0: W = out.size[0] * H // out.size[1] #bbox = orig_bbox quad = [] trans_needed = False for point in bbox_4: x = (point[0] - bbox[0]) / (bbox[2] - bbox[0]) * (out.size[0]) y = (1 - (point[1] - bbox[1]) / (bbox[3] - bbox[1])) * (out.size[1]) x = int(round(x)) y = int(round(y)) if (x is not 0 and x is not out.size[0]) or (y is not 0 and y is not out.size[1]): trans_needed = True quad.append(x) quad.append(y) if trans_needed: quad = tuple(quad) out = out.transform((W, H), Image.QUAD, quad, Image.BICUBIC) elif (W != out.size[0]) or (H != out.size[1]): "just resize" out = out.resize((W, H), Image.ANTIALIAS) # out = reproject(out, bbox, layer["proj"], request_proj) return out
def twms_main(data): """ Do main TWMS work. data - dictionary of params. returns (error_code, content_type, resp) """ start_time = datetime.datetime.now() content_type = "text/html" resp = "" srs = data.get("srs", "EPSG:4326") gpx = data.get("gpx","").split(",") wkt = data.get("wkt","") trackblend = float(data.get("trackblend","0.5")) color = data.get("color",data.get("colour","")).split(",") track = False tracks = [] if len(gpx) == 0: req_bbox = projections.from4326((27.6518898,53.8683186,27.6581944,53.8720359), srs) else: for g in gpx: local_gpx = config.gpx_cache + "%s.gpx" % g if not os.path.exists (config.gpx_cache): os.makedirs(config.gpx_cache) if not os.path.exists (local_gpx): urllib.urlretrieve ("http://www.openstreetmap.org/trace/%s/data" % g, local_gpx) if not track: track = GPXParser(local_gpx) req_bbox = projections.from4326(track.bbox, srs) else: track = GPXParser(local_gpx) req_bbox = bbox.add(req_bbox, projections.from4326(track.bbox, srs)) tracks.append(track) req_type = data.get("request","GetMap") version = data.get("version","1.1.1") ref = data.get("ref",config.service_url) if req_type == "GetCapabilities": content_type, resp = capabilities.get(version, ref) return (OK, content_type, resp) layer = data.get("layers",config.default_layers).split(",") if ("layers" in data) and not layer[0]: layer = ["transparent"] if req_type == "GetCorrections": points = data.get("points",data.get("POINTS", "")).split("=") resp = "" points = [a.split(",") for a in points] points = [(float(a[0]), float(a[1])) for a in points] req.content_type = "text/plain" for lay in layer: for point in points: resp += "%s,%s;"% tuple(correctify.rectify(config.layers[lay], point)) resp += "\n" return (OK, content_type, resp) force = tuple(data.get("force","").split(",")) filt = tuple(data.get("filter","").split(",")) if layer == [""] : content_type = "text/html" resp = overview.html(ref) return (OK, content_type, resp) format = data.get("format", config.default_format).lower() format = formats.get("image/" + format, format) format = formats.get(format, format) if format not in formats.values(): return (ERROR, content_type, "Invalid format") content_type = mimetypes[format] width=0 height=0 resp_cache_path, resp_ext = "","" if req_type == "GetTile": width=256 height=256 height = int(data.get("height",height)) width = int(data.get("width",width)) srs = data.get("srs", "EPSG:3857") x = int(data.get("x",0)) y = int(data.get("y",0)) z = int(data.get("z",1)) + 1 if "cache_tile_responses" in dir(config) and not wkt and (len(gpx) == 0): if (srs, tuple(layer), filt, width, height, force, format) in config.cache_tile_responses: resp_cache_path, resp_ext = config.cache_tile_responses[(srs, tuple(layer), filt, width, height, force, format)] resp_cache_path = resp_cache_path+"/%s/%s/%s.%s"%(z-1,x,y,resp_ext) if os.path.exists(resp_cache_path): return (OK, content_type, open(resp_cache_path, "r").read()) if len(layer) == 1: if layer[0] in config.layers: if config.layers[layer[0]]["proj"] == srs and width is 256 and height is 256 and not filt and not force and not correctify.has_corrections(layer[0]): local = config.tiles_cache + config.layers[layer[0]]["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y) ext = config.layers[layer]["ext"] adds = ["","ups."] for add in adds: if os.path.exists(local+add+ext): tile_file = open(local+add+ext, "r") resp = tile_file.read() return (OK, content_type, resp) req_bbox = projections.from4326(projections.bbox_by_tile(z,x,y,srs),srs) if data.get("bbox",None): req_bbox = tuple(map(float,data.get("bbox",req_bbox).split(","))) req_bbox = projections.to4326(req_bbox, srs) req_bbox, flip_h = bbox.normalize(req_bbox) box = req_bbox #print >> sys.stderr, req_bbox #sys.stderr.flush() height = int(data.get("height",height)) width = int(data.get("width",width)) width = min(width, config.max_width) height = min(height, config.max_height) if (width == 0) and (height == 0): width = 350 # layer = layer.split(",") imgs = 1. ll = layer.pop(0) if ll[-2:] == "!c": ll = ll[:-2] if wkt: wkt = ","+wkt wkt = correctify.corr_wkt(config.layers[ll]) + wkt srs = config.layers[ll]["proj"] try: result_img = getimg(box,srs, (height, width), config.layers[ll], start_time, force) except KeyError: result_img = Image.new("RGBA", (width,height)) #width, height = result_img.size for ll in layer: if ll[-2:] == "!c": ll = ll[:-2] if wkt: wkt = ","+wkt wkt = correctify.corr_wkt(config.layers[ll]) + wkt srs = config.layers[ll]["proj"] im2 = getimg(box, srs,(height, width), config.layers[ll], start_time, force) if "empty_color" in config.layers[ll]: ec = ImageColor.getcolor(config.layers[ll]["empty_color"], "RGBA") sec = set(ec) if "empty_color_delta" in config.layers[ll]: delta = config.layers[ll]["empty_color_delta"] for tr in range(-delta, delta): for tg in range(-delta, delta): for tb in range(-delta, delta): if (ec[0]+tr) >= 0 and (ec[0]+tr) < 256 and (ec[1]+tr) >= 0 and (ec[1]+tr) < 256 and(ec[2]+tr) >= 0 and (ec[2]+tr) < 256: sec.add((ec[0]+tr,ec[1]+tg,ec[2]+tb,ec[3])) i2l = im2.load() for x in range(0,im2.size[0]): for y in range(0,im2.size[1]): t = i2l[x,y] if t in sec: i2l[x,y] = (t[0],t[1],t[2],0) if not im2.size == result_img.size: im2 = im2.resize(result_img.size, Image.ANTIALIAS) im2 = Image.composite(im2,result_img, im2.split()[3]) # imgs/(imgs+1.)) if "noblend" in force: result_img = im2 else: result_img = Image.blend(im2, result_img, 0.5) imgs += 1. ##Applying filters result_img = filter.raster(result_img, filt, req_bbox, srs) #print >> sys.stderr, wkt #sys.stderr.flush() if wkt: result_img = drawing.wkt(wkt, result_img, req_bbox, srs, color if len(color) > 0 else None, trackblend) if len(gpx) > 0: last_color = None c = iter(color) for track in tracks: try: last_color = c.next(); except StopIteration: pass result_img = drawing.gpx(track, result_img, req_bbox, srs, last_color, trackblend) if flip_h: result_img = ImageOps.flip(result_img) image_content = StringIO.StringIO() if format == "JPEG": try: result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) except IOError: result_img.save(image_content, format, quality=config.output_quality) elif format == "PNG": result_img.save(image_content, format, progressive=config.output_progressive, optimize =config.output_optimize) elif format == "GIF": result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) else: ## workaround for GIF result_img = result_img.convert("RGB") result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive) resp = image_content.getvalue() if resp_cache_path: try: "trying to create local cache directory, if it doesn't exist" os.makedirs("/".join(resp_cache_path.split("/")[:-1])) except OSError: pass try: a = open(resp_cache_path, "w") a.write(resp) a.close() except (OSError, IOError): print >> sys.stderr, "error saving response answer to file %s." % (resp_cache_path) sys.stderr.flush() return (OK, content_type, resp)
def path_ortho(nodedata, selected): edges = [] # all edges of all ways nodes = dict() # all used nodes fixnodes = len(selected.nodes) vbase1 = [0,0] #load geometry into our arrays with additional data n=0 num = 0 anchor = [0,0] # base point, all coords will be relative to it, to remove loss of float accuracy due to big absolute value basevectorflag = 0 for wayid in selected.ways.keys(): prevnode = None prevfix = 0 if len(selected.ways[wayid][REF])==2 and basevectorflag==0: if 'fixme' in selected.ways[wayid][TAG]: if selected.ways[wayid][TAG]['fixme']=='ortho2_py_base_vector': basevectorflag = 1 # manual base vector found for nodeid in selected.ways[wayid][REF]: node = nodedata.nodes[nodeid] proj = projections.from4326((node[LON],node[LAT]), "EPSG:3857") if num==0: anchor = copy.deepcopy(proj) #first found node proj[0] -= anchor[0] proj[1] -= anchor[1] if basevectorflag==1: vbase1[0] = proj[0] vbase1[1] = proj[1] basevectorflag=2 continue elif basevectorflag==2: vbase1[0] -= proj[0] #second node of manual base vector vbase1[1] -= proj[1] basevectorflag=3 continue if nodeid in selected.nodes: fix = 1 else: n+=1 fix = 0 if not nodeid in nodes: nodes[nodeid] = [proj,copy.deepcopy(proj), [None,None], [None, None], fix] #prev coords, new coords, C-params, dirgroups, fixed flag if prevnode!= None: if fix==0 or prevfix==0: #skip edges with both fixed nodes edges.append([prevnode,nodeid,0]) #edge members: node1, node2, direction num+=1 prevnode = nodeid prevfix = fix if n==0: nodedata.addcomment("All nodes fixed, nothing to move") return 0 if basevectorflag==3: #use manual base vector vbase1 = normalize(vbase1) elif fixnodes==2: #use two selected nodes as a base vector num = 0 for nodeid in selected.nodes.keys(): if nodeid in nodes: proj = nodes[nodeid][0] #already calculated else: node = selected.nodes[nodeid] proj = projections.from4326((node[LON],node[LAT]), "EPSG:3857") proj[0] -= anchor[0] proj[1] -= anchor[1] if num==0: vbase1[0] = proj[0] vbase1[1] = proj[1] elif num==1: #just in case num became >1 vbase1[0] -= proj[0] vbase1[1] -= proj[1] num +=1 vbase1 = normalize(vbase1) else: #calculate base vector from geometry vbase2 = [0,0] #calculate two versions of base direction vector #1st on vectors in range (0;90) degrees #2nd on vectors in range (-45;45) degrees for edge in edges: n1 = edge[0] n2 = edge[1] x1 = nodes[n2][0][0]-nodes[n1][0][0] y1 = nodes[n2][0][1]-nodes[n1][0][1] d = x1*x1 + y1*y1 x1 *= d #increase length for increasing effect of longer vectors y1 *= d if x1<0: x1=-x1 y1=-y1 #(x1;y1) now in range (-90;90) degr if y1<0: x2=-y1 y2=x1 else: x2=x1 y2=y1 #(x2,y2) now in range (0;90) degr vbase1[0]+=x2 #data goes into 1st base vector vbase1[1]+=y2 if x1>abs(y1): x4=x1 y4=y1 #in range (-45;45) degr else: if y1<0: x4=-y1 y4=x1 #was in range (-90;-45) degr else: x4=y1 y4=-x1 #was in range (45;90) degr #(x4,y4) now in range (-45;45) degr vbase2[0]+=x4 #data goes into 2nd base vector vbase2[1]+=y4 #normalize both base vectors vbase1 = normalize(vbase1) vbase2 = normalize(vbase2) #calculate for both base vector square error sumv2=0 sumv4=0 for edge in edges: #path vector from one node to another n1 = edge[0] n2 = edge[1] x1 = nodes[n2][0][0]-nodes[n1][0][0] y1 = nodes[n2][0][1]-nodes[n1][0][1] #for 1st base vector v2 = x1 * vbase1[0] + y1 * vbase1[1] #length of path vector along base vector v4 = x1 * vbase1[1] - y1 * vbase1[0] #length of path vector perpendicular to base vector v2*=v2 #square v4*=v4 if v2>v4: sumv2+=v4 #path vector is along base vector, square error is defined by perpendicular else: sumv2+=v2 #path vector is perpendicular to base vector, square error is defined by along length #for 2nd base vector v2 = x1 * vbase2[0] + y1 * vbase2[1] #length of path vector along base vector v4 = x1 * vbase2[1] - y1 * vbase2[0] #length of path vector perpendicular to base vector v2*=v2 #square v4*=v4 if v2>v4: sumv4+=v4 #path vector is along base vector, square error is defined by perpendicular else: sumv4+=v2 #path vector is perpendicular to base vector, square error is defined by along length if sumv2>sumv4: #square error of 1st base vector is larger, so we will use 2nd vector as base vbase1=vbase2 #for now on vbase1 is a base vector #set directions for edge in edges: #path vector from one node to another n1 = edge[0] n2 = edge[1] x1 = nodes[n2][0][0]-nodes[n1][0][0] y1 = nodes[n2][0][1]-nodes[n1][0][1] v2 = abs(x1*vbase1[0]+y1*vbase1[1]) #length of path vector along base vector v4 = abs(x1*vbase1[1]-y1*vbase1[0]) #length of path vector perpendicular to base vector if v2>v4: edge[2]=0 #path vector is along base vector else: edge[2]=1 #path vector is perpendicular to base vector #set dirgroups #each dirgroup contains all edges having same direction (0/1, see above) and connected by nodes #all nodes from one dirgroup are projected to single line during orthogonalization grouplist=[] #list of dirgroups for edge in edges: n1 = edge[0] n2 = edge[1] dir = edge[2] if nodes[n1][3][dir]==None: if nodes[n2][3][dir]==None: #new group dirgr1 = [dir,n1,n2] #group members: dirction, node1, node2, node3.... nodes[n1][3][dir] = dirgr1 nodes[n2][3][dir] = dirgr1 grouplist.append(dirgr1) else: #add n1 to dirgroup dirgr1 = nodes[n2][3][dir] nodes[n1][3][dir]=dirgr1 dirgr1.append(n1) else: if nodes[n2][3][dir]==None: #add n2 to dirgroup dirgr1 = nodes[n1][3][dir] nodes[n2][3][dir]=dirgr1 dirgr1.append(n2) else: dirgr1 = nodes[n1][3][dir] dirgr2 = nodes[n2][3][dir] if dirgr1!=dirgr2: #combining different groups len2 = len(dirgr2) for i in range(1, len2): nodeid=dirgr2[i] nodes[nodeid][3][dir] = dirgr1 #update all nodes to dirgr1 dirgr1.append(nodeid) for i in range(0,len(grouplist)-1): #delete dirgr2 if grouplist[i]==dirgr2: grouplist.pop(i) break del dirgr2 #to free memory #calculate nodes c1/c2 parameters #C-param defines line equation A*x+B*y = C, where (A,B) - vector perpendicular to line #(A,B) is our base vector for dir=1 for dirgroup in grouplist: c = 0.0 n = 0 nfix = 0 len1 = len(dirgroup) dir = dirgroup[0] cfix = 0.0 for i in range(1, len1): nodeid = dirgroup[i] n+=1 if dir==0: c0 = nodes[nodeid][0][0]*vbase1[1]-nodes[nodeid][0][1]*vbase1[0] #perpendicular to base vector else: c0 = nodes[nodeid][0][0]*vbase1[0]+nodes[nodeid][0][1]*vbase1[1] #along base vector c += c0 if nodes[nodeid][4] == 1: #fixed node cfix += c0 nfix += 1 if n==0: c = None #protection from division by zero else: c/=n #average c-param if nfix > 0: c = cfix/nfix #fixed nodes in group - use only their c-param average for i in range(1, len1): nodeid = dirgroup[i] if nodes[nodeid][4] == 1: nodes[nodeid][2][dir] = None #fixed nodes are not moved else: nodes[nodeid][2][dir] = c #calculate new nodes positions from c1/c2 and update geometry #A*x+B*y=C1 - ortho-direction #B*x-A*y=C2 - along-direction #x=(A*C1+B*C2)/(A*A+B*B) #y=(-A*C2+B*C1)/(A*A+B*B) #where (A*A+B*B) = 1 n=0 for nodeid in nodes.keys(): if nodes[nodeid][4] == 0: #not fixed c1 = nodes[nodeid][2][0] c2 = nodes[nodeid][2][1] #calc missing cl/c2 - for ending nodes, intermediates in chains and in case of if c1==None: c1 = nodes[nodeid][0][0]*vbase1[1]-nodes[nodeid][0][1]*vbase1[0] #perpendicular to base vector if c2==None: c2 = nodes[nodeid][0][0]*vbase1[0]+nodes[nodeid][0][1]*vbase1[1] #along base vector #calc new positions nodes[nodeid][1][0]=vbase1[0]*c2+vbase1[1]*c1 #x nodes[nodeid][1][1]=-vbase1[0]*c1+vbase1[1]*c2 #y #update geometry back node = nodedata.nodes[nodeid] node_move = nodes[nodeid] if (node_move[1][0] != node_move[0][0]) or (node_move[1][1] != node_move[0][1]): node_lon,node_lat = projections.to4326((node_move[1][0]+anchor[0],node_move[1][1]+anchor[1]), "EPSG:3857") if (node[LON]!=node_lon) or (node[LAT]!=node_lat): #both checks are mainly useless, as small changes present each time node[LON]=node_lon node[LAT]=node_lat node[ACTION]=MODIFY n+=1 nodedata.addcomment("Nodes moved: "+str(n)+", fixed: "+str(fixnodes))
def getimg (bbox, request_proj, size, layer, start_time, force): orig_bbox = bbox ## Making 4-corner maximal bbox bbox_p = projections.from4326(bbox, request_proj) bbox_p = projections.to4326((bbox_p[2],bbox_p[1],bbox_p[0],bbox_p[3]), request_proj) bbox_4 = ( (bbox_p[2],bbox_p[3]),(bbox[0], bbox[1]),(bbox_p[0],bbox_p[1]),(bbox[2],bbox[3]) ) if "nocorrect" not in force: bb4 = [] for point in bbox_4: bb4.append(correctify.rectify(layer, point)) bbox_4 = bb4 bbox = bbox_utils.expand_to_point(bbox, bbox_4) #print bbox #print orig_bbox global cached_objs H,W = size max_zoom = layer.get("max_zoom",config.default_max_zoom) min_zoom = layer.get("min_zoom",1) zoom = bbox_utils.zoom_for_bbox (bbox,size,layer, min_zoom, max_zoom, (config.max_height,config.max_width)) lo1, la1, lo2, la2 = bbox from_tile_x, from_tile_y, to_tile_x, to_tile_y = projections.tile_by_bbox(bbox, zoom, layer["proj"]) cut_from_x = int(256*(from_tile_x - int(from_tile_x))) cut_from_y = int(256*(from_tile_y - int(from_tile_y))) cut_to_x = int(256*(to_tile_x - int(to_tile_x))) cut_to_y = int(256*(to_tile_y - int(to_tile_y))) from_tile_x, from_tile_y = int(from_tile_x), int(from_tile_y) to_tile_x, to_tile_y = int(to_tile_x), int(to_tile_y) bbox_im = (cut_from_x, cut_to_y, 256*(to_tile_x-from_tile_x)+cut_to_x, 256*(from_tile_y-to_tile_y)+cut_from_y ) x = 256*(to_tile_x-from_tile_x+1) y = 256*(from_tile_y-to_tile_y+1) #print >> sys.stderr, x, y #sys.stderr.flush() out = Image.new("RGBA", (x, y)) for x in range (from_tile_x, to_tile_x+1): for y in range (to_tile_y, from_tile_y+1): got_image = False im1 = tile_image (layer,zoom,x,y, start_time, real = True) if im1: if "prefix" in layer: if (layer["prefix"], zoom, x, y) not in cached_objs: if im1.is_ok: cached_objs[(layer["prefix"], zoom, x, y)] = im1 cached_hist_list.append((layer["prefix"], zoom, x, y)) #print >> sys.stderr, (layer["prefix"], zoom, x, y), cached_objs[(layer["prefix"], zoom, x, y)] #sys.stderr.flush() if len(cached_objs) >= config.max_ram_cached_tiles: del cached_objs[cached_hist_list.pop(0)] #print >> sys.stderr, "Removed tile from cache", #sys.stderr.flush() else: ec = ImageColor.getcolor(layer.get("empty_color", config.default_background), "RGBA") #ec = (ec[0],ec[1],ec[2],0) im1 = Image.new("RGBA", (256, 256), ec) out.paste(im1,((x - from_tile_x)*256, (-to_tile_y + y )*256,)) if "filter" in layer: out = filter.raster(out, layer["filter"], orig_bbox, request_proj) ## TODO: Here's a room for improvement. we could drop this crop in case user doesn't need it. out = out.crop(bbox_im) if "noresize" not in force: if (H == W) and (H == 0): W, H = out.size if H == 0: H = out.size[1]*W/out.size[0] if W == 0: W = out.size[0]*H/out.size[1] #bbox = orig_bbox quad = [] trans_needed = False for point in bbox_4: x = (point[0]-bbox[0])/(bbox[2]-bbox[0])*(out.size[0]) y = (1-(point[1]-bbox[1])/(bbox[3]-bbox[1]))*(out.size[1]) x = int(round(x)) y = int(round(y)) if (x is not 0 and x is not out.size[0]) or (y is not 0 and y is not out.size[1]): trans_needed = True quad.append(x) quad.append(y) if trans_needed: quad = tuple(quad) out = out.transform((W,H), Image.QUAD, quad, Image.BICUBIC) elif (W != out.size[0]) or (H != out.size[1]): "just resize" out = out.resize((W,H), Image.ANTIALIAS) # out = reproject(out, bbox, layer["proj"], request_proj) return out