예제 #1
0
class ModifiedOSMReverseGeocoder:
    def __init__(self, osmdb_filename, range=0.005):
        self.osmdb = OSMDB(osmdb_filename)
        self.range = range

    def __call__(self, lat, lon):
        #vertex = self.nearest_node(lat, lon, use_index=False, range=self.range)
        vertex = self.nearest_node(lat, lon, use_index=True, range=self.range)

        if vertex:
            return NearbyVertex(*vertex)
        else:
            return None

    def bounds(self):
        """return tuple representing bounding box of reverse geocoder with form 
        # (left, bottom, right, top)"""
        return self.osmdb.bounds()

    def nearest_node(self, lat, lon, use_index=True, range=0.005):
        c = self.osmdb.get_cursor()

        if use_index and self.osmdb.index:
            id = list(self.osmdb.index.nearest((lon, lat), 1))[0]

            c.execute("SELECT id, lat, lon FROM nodes WHERE id = ?", (id, ))
        else:
            c.execute(
                "SELECT id, lat, lon FROM nodes WHERE " +
                "endnode_refs > 1 AND lat > ? AND lat < ? AND lon > ? AND lon < ?",
                (lat - range, lat + range, lon - range, lon + range))

        dists = [(nid, nlat, nlon, self.haversine_miles(nlon, nlat, lon, lat))
                 for nid, nlat, nlon in c]

        if not dists:
            return (None, None, None, None)

        return min(dists, key=lambda x: x[3])

    def haversine_miles(self, lon1, lat1, lon2, lat2):
        """Calculate the great circle distance between two points
        on the earth (specified in decimal degrees)"""

        # convert decimal degrees to radians
        lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
        # haversine formula
        dlon = lon2 - lon1
        dlat = lat2 - lat1

        a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2

        c = 2 * atan2(sqrt(a), sqrt(1 - a))

        miles = 3963.0 * c

        return miles
예제 #2
0
class ModifiedOSMReverseGeocoder:
    def __init__(self, osmdb_filename, range=0.005):
        self.osmdb = OSMDB(osmdb_filename)
        self.range = range

    def __call__(self, lat, lon):
        #vertex = self.nearest_node(lat, lon, use_index=False, range=self.range)
        vertex = self.nearest_node(lat, lon, use_index=True, range=self.range)

        if vertex:
            return NearbyVertex(*vertex)
        else:
            return None

    def bounds(self):
        """return tuple representing bounding box of reverse geocoder with form 
        # (left, bottom, right, top)"""
        return self.osmdb.bounds()

    def nearest_node(self, lat, lon, use_index=True, range=0.005):
        c = self.osmdb.get_cursor()

        if use_index and self.osmdb.index:
            id = list(self.osmdb.index.nearest((lon, lat), 1))[0]

            c.execute("SELECT id, lat, lon FROM nodes WHERE id = ?", (id,))
        else:
            c.execute("SELECT id, lat, lon FROM nodes WHERE " +
                "endnode_refs > 1 AND lat > ? AND lat < ? AND lon > ? AND lon < ?",
                 (lat-range, lat+range, lon-range, lon+range))

        dists = [(nid, nlat, nlon, self.haversine_miles(nlon, nlat, lon, lat)) for nid, nlat, nlon in c]

        if not dists:
            return (None, None, None, None)

        return min(dists, key=lambda x:x[3])

    def haversine_miles(self, lon1, lat1, lon2, lat2):
        """Calculate the great circle distance between two points
        on the earth (specified in decimal degrees)"""

        # convert decimal degrees to radians
        lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
        # haversine formula
        dlon = lon2 - lon1
        dlat = lat2 - lat1

        a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2

        c = 2 * atan2(sqrt(a), sqrt(1 - a))

        miles = 3963.0 * c

        return miles
예제 #3
0
class OSMReverseGeocoder:
    def __init__(self, osmdb_filename):
        self.osmdb = OSMDB( osmdb_filename )
        
    def __call__(self, lat, lon):
        nearby_vertex = list(self.osmdb.nearest_node(lat, lon))
        return "osm-%s"%(nearby_vertex[0])
        
    def bounds(self):
        """return tuple representing bounding box of reverse geocoder with form (left, bottom, right, top)"""
        
        return self.osmdb.bounds()
예제 #4
0
class OSMReverseGeocoder:
    def __init__(self, osmdb_filename):
        self.osmdb = OSMDB(osmdb_filename)

    def __call__(self, lat, lon):
        nearby_vertex = list(self.osmdb.nearest_node(lat, lon))
        return "osm-%s" % (nearby_vertex[0])

    def bounds(self):
        """return tuple representing bounding box of reverse geocoder with form (left, bottom, right, top)"""

        return self.osmdb.bounds()
예제 #5
0
class ContourServer(Servable):
    def __init__(self, settings_filename):
        settings = yaml.load( open( settings_filename ) )
        
        self.home_point = settings['center']
        
        # create cache of osm-node positions
        self.osmdb = OSMDB( settings['osmdb_filename'] )
        self.gtfsdb = GTFSDatabase( settings['gtfsdb_filename'] )
        self.port = settings['port']
        self.node_positions = {}
        self.index = Rtree()
        for node_id, tags, lat, lon in self.osmdb.nodes():
            self.node_positions[node_id] = (lon,lat)
            self.index.add( int(node_id), (lon,lat,lon,lat) )
        
        # incarnate graph from graphdb
        graphdb = GraphDatabase( settings['graphdb_filename'] )
        self.graph = graphdb.incarnate()
    
    def strgraph(self):
        return str(self.graph)
    
    def vertices(self):
        return "\n".join( [vv.label for vv in self.graph.vertices] )
    
    def _get_important_routes(self, spt):
        # set edge thicknesses
        t0 = time.time()
        print "setting thicknesses"
        spt.set_thicknesses( vertex_label )
        t1 = time.time()
        print "took %s"%(t1-t0)
        
        t0 = time.time()
        print "finding gateway boardings"
        # use thicknesses to determine important boardings
        origin = spt.get_vertex( vertex_label )
        sum_thickness = sum( [edge.thickness for edge in origin.outgoing] )
        
        important_boardings = sorted( filter(lambda x: x.payload.__class__==core.TripBoard and \
                                                        x.thickness/float(sum_thickness) > 0.01, spt.edges),
                                      key = lambda x:x.thickness )
                                               
        for edge in important_boardings:
            print "gateway to %f%% vertices"%(100*edge.thickness/float(sum_thickness))
            print "hop onto trip '%s' at stop '%s', time '%s'"%(edge.to_v.payload.trip_id, edge.from_v.label, edge.to_v.payload.time)
        print "took %ss"%(time.time()-t0)
    
    def _points(self, vertex_label, starttime, cutoff, speed):
        starttime = starttime or time.time()
        
        #=== find shortest path tree ===
        print "Finding shortest path tree"
        t0 = time.time()
        wo = WalkOptions()
        wo.walking_speed = speed
        spt = self.graph.shortest_path_tree( vertex_label, None, State(1,starttime), wo, maxtime=starttime+int(cutoff*1.25) )
        wo.destroy()
        t1 = time.time()
        print "took %s s"%(t1-t0)
        
        #=== cobble together ETA surface ===
        print "Creating ETA surface from OSM points..."
        points = []
        t0 = time.time()
        for vertex in spt.vertices:
            if "osm" in vertex.label:
                x, y = self.node_positions[vertex.label[3:]]
                points.append( (x, y, vertex.payload.time-starttime) )
        t1 = time.time()
        print "Took %s s"%(t1-t0)
        
        spt.destroy()
        
        return points
    
    def _contour(self, vertex_label, starttime, cutoff, step=None, speed=0.85):
        points = self._points( vertex_label, starttime, cutoff, speed )
        
        #=== create contour ===
        print "creating contour...",
        
        t0 = time.time()
        contours = travel_time_contour( points, cutoff=cutoff, cellsize=0.004, fudge=1.7, step=step )
        print "%s sec"%(time.time()-t0)
        
        print "done. here you go..."
        return contours
    
    def label_contour(self, vertex_label, starttime=None, cutoff=1800):
        starttime = starttime or time.time()
        
        return json.dumps( self._contour( vertex_label, starttime, cutoff ) )
    
    def contour(self, lat, lon, year, month, day, hour, minute, second, cutoff, step=60*15, encoded=False, speed=0.85):
        if step is not None and step < 600:
            raise Exception( "Step cannot be less than 600 seconds" )
        
        starttime = TimeHelpers.localtime_to_unix( year, month, day, hour, minute, second, "America/Los_Angeles" )
        
        #=== get osm vertex ==
        print( "getting nearest vertex" )
        
        #find osmid of origin intersection
        t0 = time.time()
        range = 0.001
        bbox = (lon-range, lat-range, lon+range, lat+range)
        candidates = self.index.intersection( bbox )
        vlabel, vlat, vlon, vdist = self.osmdb.nearest_of( lat, lon, candidates )
        t1 = time.time()
        print( "done, took %s seconds"%(t1-t0) )
        
        #vlabel, vlat, vlon, vdist = self.osmdb.nearest_node( lat, lon )
        
        if vlabel is None:
            return json.dumps( "NO NEARBY INTERSECTION" )
        
        print( "found - %s"%vlabel )
        
        contours = self._contour( "osm"+vlabel, starttime, cutoff, step, speed )
        
        if encoded:
            encoded_contours = []
            for contour in contours:
                encoded_contour = []
                for ring in contour:
                    encoded_contour.append( encode_pairs( [(lat,lon) for lon,lat in ring] ) )
                encoded_contours.append( encoded_contour )
                
            contours = encoded_contours
        
        return json.dumps( contours )

    def _surface(self, lat, lon, year, month, day, hour, minute, second, cutoff, speed, cellsize=0.004):
        
        starttime = TimeHelpers.localtime_to_unix( year, month, day, hour, minute, second, "America/Los_Angeles" )
        
        #=== get osm vertex ==
        print( "getting nearest vertex" )
        
        #find osmid of origin intersection
        t0 = time.time()
        range = 0.001
        bbox = (lon-range, lat-range, lon+range, lat+range)
        candidates = self.index.intersection( bbox )
        vlabel, vlat, vlon, vdist = self.osmdb.nearest_of( lat, lon, candidates )
        t1 = time.time()
        print( "done, took %s seconds"%(t1-t0) )
        
        #vlabel, vlat, vlon, vdist = self.osmdb.nearest_node( lat, lon )
        
        if vlabel is None:
            return json.dumps( "NO NEARBY INTERSECTION" )
        
        print( "found - %s"%vlabel )
        
        #=== get points which comprise ETA surface ===
        points = self._points( "osm"+vlabel, starttime, cutoff, speed )
        
        #=== create regular grid from ETA surface ===
        print "creating surface...",
        
        t0 = time.time()
        ret = points_to_surface_grid( points, cutoff=cutoff, fudge=1.1, margin=2, closure_tolerance=0.05, cellsize=cellsize )
        #ret = travel_time_surface( points, cutoff=cutoff, cellsize=0.004, fudge=1.7 )
        print "%s sec"%(time.time()-t0)
        print "done. here you go..."
        
        return ret

    def surface(self, lat, lon, year, month, day, hour, minute, second, cutoff, speed=0.85):
        return json.dumps( self._surface(lat,lon,year,month,day,hour,minute,second,cutoff,speed).to_matrix() )
        
    def transitability(self, lat, lon, year, month, day, hour, minute, second, cutoff, speed=0.85):
        grid = self._surface(lat,lon,year,month,day,hour,minute,second,cutoff,speed)
        
        if type(grid) == str:
            return None
        
        ret = 0
        for i in range(10):
            contourslice=sum( [len(filter(lambda x:x[2]<=(cutoff/10.0)*(i+1),col)) for col in grid] )
            print contourslice
            ret += contourslice
        
        return ret
            
    def transitability_surface(self, left, bottom, right, top, res, year, month, day, hour, minute, second, cutoff, speed=0.85):
        step = (right-left)/res
        
        return json.dumps([[(lon,lat,self.transitability(lat,lon,year,month,day,hour,minute,second,cutoff,speed)) for lat in frange(bottom,top,step)] for lon in frange(left,right,step)])
        
    def nodes(self):
        return "\n".join( ["%s-%s"%(k,v) for k,v in self.node_positions.items()] )
            
    def nearest_node(self, lat, lon):
        range = 0.005
        bbox = (lon-range, lat-range, lon+range, lat+range)
        print bbox
        print self.index.intersection( bbox )
        
        return json.dumps(self.osmdb.nearest_node( lat, lon ))
        
    def bounds(self):
        return json.dumps(self.osmdb.bounds())
    
    def run_test_server(self):
        Servable.run_test_server(self, self.port)
예제 #6
0
class RouteServer(Servable):
    def __init__(self, ch_basename, osmdb_filename, profiledb_filename):
        graphdb = GraphDatabase( graphdb_filename )
        self.osmdb = OSMDB( osmdb_filename )
        self.profiledb = ProfileDB( profiledb_filename )
        self.ch = reincarnate_ch( ch_basename )
        self.shortcut_cache = ShortcutCache( ch_basename+".scc" )
    
    def vertices(self):
        return "\n".join( [vv.label for vv in self.graph.vertices] )
    vertices.mime = "text/plain"

    def path(self, lat1, lng1, lat2, lng2, transfer_penalty=0, walking_speed=1.0, hill_reluctance=20, narrative=True, jsoncallback=None):
        
        t0 = time.time()
        origin = "osm-%s"%self.osmdb.nearest_node( lat1, lng1 )[0]
        dest = "osm-%s"%self.osmdb.nearest_node( lat2, lng2 )[0]
        endpoint_find_time = time.time()-t0
        
        print origin, dest
        
        t0  = time.time()
        wo = WalkOptions()
        #wo.transfer_penalty=transfer_penalty
        #wo.walking_speed=walking_speed
        wo.walking_speed=4
        wo.walking_overage = 0
        wo.hill_reluctance = 20
        wo.turn_penalty = 15 
        
        edgepayloads = self.ch.shortest_path( origin, dest, State(1,0), wo )
        
        wo.destroy()
        
        route_find_time = time.time()-t0
        
        t0 = time.time()
        names = []
        geoms = []
        
        profile = Profile()
        total_dist = 0
        total_elev = 0
        
        if narrative:
            names, total_dist = get_full_route_narrative( self.osmdb, edgepayloads )
        
        for edgepayload in edgepayloads:
            geom, profile_seg = self.shortcut_cache.get( edgepayload.external_id )
            
            #geom = get_ep_geom( self.osmdb, edgepayload )
            #profile_seg = get_ep_profile( self.profiledb, edgepayload )

            geoms.extend( geom )
            profile.add( profile_seg )
            
        route_desc_time = time.time()-t0

        ret = json.dumps( (names, 
                           encode_pairs( [(lat, lon) for lon, lat in geoms] ), 
                           profile.concat(300),
                           { 'route_find_time':route_find_time,
                             'route_desc_time':route_desc_time,
                             'endpoint_find_time':endpoint_find_time,},
                           { 'total_dist':total_dist,
                             'total_elev':total_elev}) )
        if jsoncallback:
            return "%s(%s)"%(jsoncallback,ret)
        else:
            return ret

    """
    def path_raw(self, origin, dest, currtime):
        
        wo = WalkOptions()
        spt = self.graph.shortest_path_tree( origin, dest, State(1,currtime), wo )
        wo.destroy()
        
        vertices, edges = spt.path( dest )
        
        ret = "\n".join([str(x) for x in vertices]) + "\n\n" + "\n".join([str(x) for x in edges])

        spt.destroy()
        
        return ret
    """
        
    def bounds(self, jsoncallback=None):
        ret = json.dumps( self.osmdb.bounds() )
        if jsoncallback:
            return "%s(%s)"%(jsoncallback,ret)
        else:
            return ret
예제 #7
0
class RouteServer(Servable):
    def __init__(self, ch_basename, osmdb_filename, profiledb_filename):
        graphdb = GraphDatabase(graphdb_filename)
        self.osmdb = OSMDB(osmdb_filename)
        self.profiledb = ProfileDB(profiledb_filename)
        self.ch = reincarnate_ch(ch_basename)
        self.shortcut_cache = ShortcutCache(ch_basename + ".scc")

    def vertices(self):
        return "\n".join([vv.label for vv in self.graph.vertices])

    vertices.mime = "text/plain"

    def path(self,
             lat1,
             lng1,
             lat2,
             lng2,
             transfer_penalty=0,
             walking_speed=1.0,
             hill_reluctance=20,
             narrative=True,
             jsoncallback=None):

        t0 = time.time()
        origin = "osm-%s" % self.osmdb.nearest_node(lat1, lng1)[0]
        dest = "osm-%s" % self.osmdb.nearest_node(lat2, lng2)[0]
        endpoint_find_time = time.time() - t0

        print origin, dest

        t0 = time.time()
        wo = WalkOptions()
        #wo.transfer_penalty=transfer_penalty
        #wo.walking_speed=walking_speed
        wo.walking_speed = 4
        wo.walking_overage = 0
        wo.hill_reluctance = 20
        wo.turn_penalty = 15

        edgepayloads = self.ch.shortest_path(origin, dest, State(1, 0), wo)

        wo.destroy()

        route_find_time = time.time() - t0

        t0 = time.time()
        names = []
        geoms = []

        profile = Profile()
        total_dist = 0
        total_elev = 0

        if narrative:
            names, total_dist = get_full_route_narrative(
                self.osmdb, edgepayloads)

        for edgepayload in edgepayloads:
            geom, profile_seg = self.shortcut_cache.get(
                edgepayload.external_id)

            #geom = get_ep_geom( self.osmdb, edgepayload )
            #profile_seg = get_ep_profile( self.profiledb, edgepayload )

            geoms.extend(geom)
            profile.add(profile_seg)

        route_desc_time = time.time() - t0

        ret = json.dumps(
            (names, encode_pairs([(lat, lon) for lon, lat in geoms]),
             profile.concat(300), {
                 'route_find_time': route_find_time,
                 'route_desc_time': route_desc_time,
                 'endpoint_find_time': endpoint_find_time,
             }, {
                 'total_dist': total_dist,
                 'total_elev': total_elev
             }))
        if jsoncallback:
            return "%s(%s)" % (jsoncallback, ret)
        else:
            return ret

    """
    def path_raw(self, origin, dest, currtime):
        
        wo = WalkOptions()
        spt = self.graph.shortest_path_tree( origin, dest, State(1,currtime), wo )
        wo.destroy()
        
        vertices, edges = spt.path( dest )
        
        ret = "\n".join([str(x) for x in vertices]) + "\n\n" + "\n".join([str(x) for x in edges])

        spt.destroy()
        
        return ret
    """

    def bounds(self, jsoncallback=None):
        ret = json.dumps(self.osmdb.bounds())
        if jsoncallback:
            return "%s(%s)" % (jsoncallback, ret)
        else:
            return ret
예제 #8
0
    i = 0
    while i < len(l):
        while isinstance(l[i], ltypes):
            if not l[i]:
                l.pop(i)
                i -= 1
                break
            else:
                l[i:i + 1] = l[i]
        i += 1
    return ltype(l)


if __name__ == '__main__':

    COLORS = {
        'motorway': ((1,0,0,1), 2),
        'motorway_link': ((1,0,0,1), 1.5),
        }
    
    out, filename, w, h = sys.argv[1:]
    db = OSMDB(filename)
    b = db.bounds()
    r = GeographicCanvas(int(w), int(h), b, mode='svg', fobj=open(out,'wb'))
    r.background()
    for way_id, parent_id, from_nd, to_nd, dist, geom, tags in db.edges():
        color, stroke = COLORS.get(tags.get('highway'),((0,0,0,.8),0.8))
        r.line(coords=flatten(geom), cstroke=color, stroke=stroke)

    #r.write_to_png(out)