def findEdges(self): """Update the projection meta-info based on its fundamental parameters""" if(not self.xyValid): # If the display is not known yet, then we can't do anything, but we'll # mark it as something that needs doing as soon as the display # becomes valid self.needsEdgeFind = True return # Find the map centre in projection units self.px, self.py = latlon2xy(self.lat,self.lon,self.zoom) # Find the map edges in projection units self.px1 = self.px - 0.5 * self.w / self.scale self.px2 = self.px + 0.5 * self.w / self.scale self.py1 = self.py - 0.5 * self.h / self.scale self.py2 = self.py + 0.5 * self.h / self.scale # Store width and height in projection units, just to save time later self.pdx = self.px2 - self.px1 self.pdy = self.py2 - self.py1 # Calculate the bounding box # ASSUMPTION: (that the projection is regular and north-up) self.N,self.W = xy2latlon(self.px1, self.py1, self.zoom) self.S,self.E = xy2latlon(self.px2, self.py2, self.zoom) # Mark the meta-info as valid self.needsEdgeFind = False
def getImageATLatLon(self, lat, lon): image = self.loadTileSet(lat, lon) x, y = tilenames.latlon2pixels(lat, lon, self.zoom) x *= self.tileSize y *= self.tileSize sx = image.size[0] sy = image.size[1] tsx = self.w tsy = self.h offx = self.tileSize / 2 - x offy = self.tileSize / 2 - y cropped = image.crop( ( int(sx / 2 - tsx / 2 - offx), int(sy / 2 - tsy / 2 - offy), int(sx / 2 + tsx / 2 - offx), int(sy / 2 + tsy / 2 - offy), ) ) # get bounds (seems to be slightly off!) x, y = tilenames.latlon2xy(lat, lon, self.zoom) print tilenames.xy2latlon(x, y, self.zoom) ul_lat, ul_lon = tilenames.xy2latlon( x - (tsx / 2 + offx) / self.tileSize, y - (tsy / 2 + offy) / self.tileSize, self.zoom ) lr_lat, lr_lon = tilenames.xy2latlon( x + (tsx / 2 + offx) / self.tileSize, y + (tsy / 2 + offy) / self.tileSize, self.zoom ) self.bounds = ul_lon, ul_lat, lr_lon, lr_lat print self.bounds return cropped
def findEdges(self): """Update the projection meta-info based on its fundamental parameters""" if (not self.xyValid): # If the display is not known yet, then we can't do anything, but we'll # mark it as something that needs doing as soon as the display # becomes valid self.needsEdgeFind = True return # Find the map centre in projection units self.px, self.py = latlon2xy(self.lat, self.lon, self.zoom) # Find the map edges in projection units self.px1 = self.px - 0.5 * self.w / self.scale self.px2 = self.px + 0.5 * self.w / self.scale self.py1 = self.py - 0.5 * self.h / self.scale self.py2 = self.py + 0.5 * self.h / self.scale # Store width and height in projection units, just to save time later self.pdx = self.px2 - self.px1 self.pdy = self.py2 - self.py1 # Calculate the bounding box # ASSUMPTION: (that the projection is regular and north-up) self.N, self.W = xy2latlon(self.px1, self.py1, self.zoom) self.S, self.E = xy2latlon(self.px2, self.py2, self.zoom) # Mark the meta-info as valid self.needsEdgeFind = False
def load(self, filename, optimise = True): """Load an OSM XML file into memory""" if not os.path.exists(filename): print "File doesn't exist: '%s'" % filename return [] f = file(filename, "rb") size = os.path.getsize(filename) while f.tell() < size: way = {'n':[]} wayID = struct.unpack("I", f.read(4))[0] numNodes = struct.unpack("I", f.read(4))[0] for n in range(numNodes): (x,y,nid) = struct.unpack("III", f.read(3*4)) (lat,lon) = tilenames.xy2latlon(x,y,31) way['n'].append((lat,lon,nid)) way['style'] = struct.unpack("I", f.read(4))[0] way['layer'] = struct.unpack("b", f.read(1))[0] tagSize = struct.unpack("H", f.read(2))[0] c = 0 while c < tagSize: k = f.read(1) s = struct.unpack("H", f.read(2))[0] v = f.read(s) way[k] = v c += 3 + s self.ways[wayID] = way if optimise: self.optimise()
def nudge(self, dx, dy): """Move the map by a number of pixels relative to its current position""" if dx == 0 and dy == 0: return # Calculate the lat/long of the pixel offset by dx,dy from the centre, # and centre the map on that newXC = self.px - dx / self.scale newYC = self.py - dy / self.scale self.lat, self.lon = xy2latlon(newXC, newYC, self.zoom) self.findEdges()
def nudge(self,dx,dy): """Move the map by a number of pixels relative to its current position""" if dx == 0 and dy == 0: return # Calculate the lat/long of the pixel offset by dx,dy from the centre, # and centre the map on that newXC = self.px - dx / self.scale newYC = self.py - dy / self.scale self.lat,self.lon = xy2latlon(newXC,newYC, self.zoom) self.findEdges()
def loadOsm(self, filename): if(not os.path.exists(filename)): print "No such data file %s" % filename return(False) fp = open(filename, "r") re_way = re.compile("<way id='(\d+)'>\s*$") re_nd = re.compile("\s+<nd id='(\d+)' x='(\d+)' y='(\d+)' />\s*$") re_tag = re.compile("\s+<tag k='(.*)' v='(.*)' />\s*$") re_endway = re.compile("</way>$") in_way = 0 way_tags = {} way_nodes = [] for line in fp: result_way = re_way.match(line) result_endway = re_endway.match(line) if(result_way): in_way = True way_tags = {} way_nodes = [] way_id = int(result_way.group(1)) elif(result_endway): in_way = False self.storeWay(way_id, way_tags, way_nodes) elif(in_way): result_nd = re_nd.match(line) if(result_nd): node_id = int(result_nd.group(1)) x = float(result_nd.group(2)) y = float(result_nd.group(3)) (lat,lon) = tilenames.xy2latlon(x,y,31) way_nodes.append([node_id,lat,lon]) else: result_tag = re_tag.match(line) if(result_tag): way_tags[result_tag.group(1)] = result_tag.group(2) return(True)
def loadOsm(self, filename): if not os.path.exists(filename): print("No such data file %s" % filename) return False fp = open(filename, "r") re_way = re.compile("<way id='(\d+)'>\s*$") re_nd = re.compile("\s+<nd id='(\d+)' x='(\d+)' y='(\d+)' />\s*$") re_tag = re.compile("\s+<tag k='(.*)' v='(.*)' />\s*$") re_endway = re.compile("</way>$") in_way = 0 way_tags = {} way_nodes = [] for line in fp: result_way = re_way.match(line) result_endway = re_endway.match(line) if (result_way): in_way = True way_tags = {} way_nodes = [] way_id = int(result_way.group(1)) elif result_endway: in_way = False self.storeWay(way_id, way_tags, way_nodes) elif in_way: result_nd = re_nd.match(line) if result_nd: node_id = int(result_nd.group(1)) x = float(result_nd.group(2)) y = float(result_nd.group(3)) (lat, lon) = tilenames.xy2latlon(x, y, 31) way_nodes.append([node_id, lat, lon]) else: result_tag = re_tag.match(line) if result_tag: way_tags[result_tag.group(1)] = result_tag.group(2) return True
def loadOsm(self, osmtiledata): re_way = re.compile("<way id='(\d+)'>\s*$") re_nd = re.compile("\s+<nd id='(\d+)' x='(\d+)' y='(\d+)' />\s*$") re_tag = re.compile("\s+<tag k='(.*)' v='(.*)' />\s*$") re_endway = re.compile("</way>$") in_way = 0 way_tags = {} way_nodes = [] for line in osmtiledata: result_way = re_way.match(line) result_endway = re_endway.match(line) if(result_way): in_way = True way_tags = {} way_nodes = [] way_id = int(result_way.group(1)) elif(result_endway): in_way = False self.storeWay(way_id, way_tags, way_nodes) elif(in_way): result_nd = re_nd.match(line) if(result_nd): node_id = int(result_nd.group(1)) x = float(result_nd.group(2)) y = float(result_nd.group(3)) (lat,lon) = tilenames.xy2latlon(x,y,31) way_nodes.append([node_id,lat,lon]) else: result_tag = re_tag.match(line) if(result_tag): way_tags[result_tag.group(1)] = result_tag.group(2) #~ logging.debug("statistics: routable nodes(%s)" % (len(self.rnodes))) return(True)
def xy2ll(self, x, y): """Convert display units to geographic units""" px = self.px1 + x / self.scale py = self.py1 + y / self.scale lat, lon = xy2latlon(px, py, self.zoom) return (lat, lon)
def xy2ll(self,x,y): """Convert display units to geographic units""" px = self.px1 + x / self.scale py = self.py1 + y / self.scale lat,lon = xy2latlon(px, py, self.zoom) return(lat,lon)