Example #1
0
    def get_rtree_index(self):
        """
        Get an rtree index of the edges within this GeoGraph

        Returns:
            rtree:  rtree of edges indexed by bounding_box (4 coordinates)
                allowing lookup of the edge (node1, node2) and it's segment
        """
        def edge_generator():
            edges_bounds = map(lambda tup: (tup, gm.make_bounding_box(
                    *map(lambda n: self.coords[n], tup))), self.edges())

            for edge, box in edges_bounds:
                # Object is in form of (u.label, v.label), (u.coord, v.coord)
                yield (hash(edge), box, (edge,
                            map(lambda ep: np.array(self.coords[ep]), edge)))

        # something's not working right with latest version of rtree/spatial lib
        # index where we need to insert the objects in a loop rather than
        # via a generator to their constructor
        # Init rtree and store grid edges
        rtree = Rtree()
        for e in edge_generator():
            rtree.insert(e[0], e[1], e[2])    

        return rtree
Example #2
0
def polygons_enclosure_tree(polygons):
    '''
    Given a list of shapely polygons, which are the root (aka outermost)
    polygons, and which represent the holes which penetrate the root
    curve. We do this by creating an R-tree for rough collision detection,
    and then do polygon queries for a final result
    '''
    tree = Rtree()
    for i, polygon in enumerate(polygons):
        tree.insert(i, polygon.bounds)

    count = len(polygons)
    g     = nx.DiGraph()
    g.add_nodes_from(np.arange(count))
    for i in range(count):
        if polygons[i] is None: continue
        #we first query for bounding box intersections from the R-tree
        for j in tree.intersection(polygons[i].bounds):
            if (i==j): continue
            #we then do a more accurate polygon in polygon test to generate
            #the enclosure tree information
            if   polygons[i].contains(polygons[j]): g.add_edge(i,j)
            elif polygons[j].contains(polygons[i]): g.add_edge(j,i)
    roots = [n for n, deg in list(g.in_degree().items()) if deg==0]
    return roots, g
Example #3
0
def segment_spatial_index(linestring):
    coords = list(linestring.coords)
    spatial_index = Rtree()
    for i in range(len(coords)-1):
        x = map(lambda xy: xy[0],coords[i:i+2])
        y = map(lambda xy: xy[1],coords[i:i+2])
        spatial_index.add(i,(min(x),min(y),max(x),max(y)))
    return spatial_index
Example #4
0
    def __call__(self, container, name, args):
        copts, cargs = self.parser.parse_args(args)
        data = os.path.join(container.opts.data, name)

        # First, pack the ZODB
        storage = FileStorage.FileStorage("%s/var/Data.fs" % data)
        db = DB(storage)
        db.pack()

        # Can't pack an Rtree's storage in-place, so we move it away and 
        # recreate from the contents of the ZODB
        rtree = None
        rtree_filename = '%s/var/vrt1' % data
 
        try:
            shutil.move(rtree_filename + ".dat", rtree_filename + ".bkup.dat")
            shutil.move(rtree_filename + ".idx", rtree_filename + ".bkup.idx")
        
            conn = db.open()
            root = conn.root()
            keys = root['index'].keys

            bkup = Rtree('%s/var/vrt1.bkup' % data)
            pagesize = bkup.properties.pagesize

            if len(keys) == 0:
                fwd = Rtree(
                        '%s/var/vrt1' % data,
                        # Passing in copied properties doesn't work,
                        # leading to errors involving page ids
                        # properties=new_properties, 
                        pagesize=pagesize
                        )
            else:
                gen = ((intid, bbox, None) for intid, (uid, bbox) \
                      in keys.items())
                fwd = Rtree(
                        '%s/var/vrt1' % data,
                        gen, 
                        # Passing in copied properties doesn't work,
                        # leading to errors involving page ids
                        # properties=new_properties,
                        pagesize=pagesize
                        )
            
            conn.close()
            db.close()
            storage.close()
        except:
            # Restore backups
            shutil.copy(rtree_filename + ".bkup.dat", rtree_filename + ".dat")
            shutil.copy(rtree_filename + ".bkup.idx", rtree_filename + ".idx")
            raise
        finally:
            if fwd is not None:
                fwd.close()
Example #5
0
 def __init__(self):
     self.nodes = {} # indexed by node id
     self.edges = {} # indexed by edge id
     self.intersections = {} # indexed by node id
     self.node_spatial_index = Rtree()
     self.edge_spatial_index = Rtree()
     self.intersection_spatial_index = Rtree()
     self.edge_lookup_table = {} # indexed by (in_node,out_node)
     self.edge_coords_lookup_table = {} # indexed by (in_node.coords, out_node.coords)
     self.segments = {} # indexed by segment id
     self.segment_lookup_table = {} # indexed by (head_edge.in_node, tail_edge.out_node)
 def __init__(self):
     self.GPS = GPS()
     self.idx = Rtree()
     self.nodeidx = Rtree()
     self.G = None
     self.edgeindex_edge = {}
     self.edgecounter = 0
     self.nodecounter = 0
     self.gps_points = [];
     self.edge_id__count = {}
     self.node_counter__node = {}
Example #7
0
class Dispatch:
    def __init__(self, config_filename):
        self.index = Rtree()
        
        # get children from yaml file
        config_str = open(config_filename).read()
        print config_str
        self.children = yaml.load( config_str )
        
        # index children according to their bounding box
        for i, child in enumerate(self.children):
            self.index.add(i, child['bounds'])
    
    def register(self, baseurl, left, bottom, right, top):
        if baseurl in self.children.values():
            raise Exception( "Child with baseurl '%s' already registered"%baseurl )
        
        childindex = len(self.children)
        self.children[childindex] = (baseurl, (left,bottom,right,top))
        self.index.add( childindex, (left, bottom, right, top) )
        
        return json.dumps(self.children)
        
    def children(self):
        return json.dumps( self.children )
        
    def _over(self, lat, lon):
        return [self.children[x] for x in self.index.intersection( (lon, lat, lon, lat) )]
            
    def contour(self, lat, lon, year, month, day, hour, minute, second, cutoff, step=60*15, encoded=False, speed=0.85):
        child_servers = self._over( lat, lon )
        if len(child_servers) == 0:
            return "NO SHEDS HERE"
        
        child_server = child_servers[0]
        args = {'lat':lat,
                'lon':lon,
                'year':year,
                'month':month,
                'day':day,
                'hour':hour,
                'minute':minute,
                'second':second,
                'cutoff':cutoff,
                'step':step,
                'speed':speed}
        contoururl = "http://%s/contour?%s&encoded=true"%(child_server['url'], urlencode(args))
        return urlopen(contoururl).read()
 def __init__(self, bus_trips):
     self.bus_trips = bus_trips
     self.graph_nodes = {} # indexed by "location_id"
     self.graph_edge_id = 0
     self.graph_edges = {} # indexed by "edge id"
     self.graph_edge_lookup = {} # indexed by "location1_id,location2_id"
     self.graph_edge_index = Rtree()
Example #9
0
def getRGsForBox(request):
    l = float( request.GET['x1'] )
    b = float( request.GET['y1'] )
    r = float( request.GET['x2'] )
    t = float( request.GET['y2'] )
    
    index = Rtree('/home/renci/geoanalytics/geoanalytics-lib/rg')
    ids = list(index.intersection((l,b,r,t), objects=True))
    rgs = []
    if len(ids) > 0:
        rgs = [{
            'name' : r.name,
            'filepath' : r.filepath, 
            'bounds' : r.bbox4326, 
            'seriescount' : Series.objects(record_group=r).count() 
        } for r in [RecordGroup.objects(id=i.object).first() for i in ids]]
    return HttpResponse(json.dumps(rgs), mimetype='application/json')
Example #10
0
 def clear(self):
     print "clear canvas!"
     self._zoom_level = self._ratio_index.index(1)
     self._offset = Point(0, 0)
    
     self._shapes = []
     #self._cairo_paths = {}
     self._index_rtree = Rtree()
     self._styler.load_default_style()
Example #11
0
def points_in_mesh(points, mesh):
    from rtree import Rtree
    points = np.array(points)
    tri_3D = mesh.vertices[mesh.faces]
    tri_2D = tri_3D[:,:,0:2]
    z_bounds = np.column_stack((np.min(tri_3D[:,:,2], axis=1),
                                np.max(tri_3D[:,:,2], axis=1)))
    bounds = np.column_stack((np.min(tri_2D, axis=1), 
                              np.max(tri_2D, axis=1)))
    tree = Rtree()
    for i, bound in enumerate(bounds):
        tree.insert(i, bound)

    result = np.zeros(len(points), dtype=np.bool)
    for point_index, point in enumerate(points):
        intersections = np.array(list(tree.intersection(point[0:2].tolist())))
        in_triangle   = [point_in_triangle_2D(point[0:2], tri_2D[i]) for i in intersections]
        result[point_index] = np.int(np.mod(np.sum(in_triangle), 2)) == 0
    return result
Example #12
0
def getSeriesForBox(request):
    l = float( request.GET['x1'] )
    b = float( request.GET['y1'] )
    r = float( request.GET['x2'] )
    t = float( request.GET['y2'] )
    rg = request.GET['rg']

    index = Rtree('/home/renci/geoanalytics/geoanalytics-lib/sr')
    ids = list(index.intersection((l,b,r,t), objects=True))
    if len(ids)> 0:
        sers = [{
            'name' : s.name,
            'filepath' : s.filepath,
            'bounds' : s.bbox4326,
            'filecount' : VectorFile.objects(series=s).count() + RasterFile.objects(series=s).count()
        } for s in [Series.objects(id=i.object[0]).first() for i in filter(lambda x:x.object[1] == rg, ids)]]
        return HttpResponse(json.dumps(sers), mimetype='application/json')
    else:
        return HttpResponse("[]", mimetype='application/json')
Example #13
0
    def __init__(self, hmm, emission_probability, constraint_length=10, MAX_DIST=500, priors=None, smallV=0.00000000001):                
        # initialize spatial index
        self.previous_obs = None

        if priors == None:
            priors=dict([(state,1.0/len(hmm)) for state in hmm])

        state_spatial_index = Rtree()
        unlocated_states = []
        id_to_state = {}
        id = 0
        for state in hmm: 
            geom=self.geometry_of_state(state)            
            if not geom:
                unlocated_states.append(state)
            else:
                ((lat1,lon1),(lat2,lon2))=geom
                state_spatial_index.insert(id,
                                           (min(lon1, lon2), min(lat1, lat2), 
                                            max(lon1, lon2), max(lat1, lat2)))
                id_to_state[id]=state
                id=id+1
            
        def candidate_states(obs): #was (lat,lon) in place of obs 
            geom = self.geometry_of_observation(obs)
            if geom == None:
                return hmm.keys()
            else:
                (lat,lon)=geom
                nearby_states = state_spatial_index.intersection((lon-MAX_DIST/METERS_PER_DEGREE_LONGITUDE,
                                                                  lat-MAX_DIST/METERS_PER_DEGREE_LATITUDE,
                                                                  lon+MAX_DIST/METERS_PER_DEGREE_LONGITUDE,
                                                                  lat+MAX_DIST/METERS_PER_DEGREE_LATITUDE))

                candidates = [id_to_state[id] for id in nearby_states]+unlocated_states
                return candidates

        self.viterbi = Viterbi(hmm,emission_probability,
                               constraint_length=constraint_length,
                               priors=priors,
                               candidate_states=candidate_states,
                               smallV=smallV)
Example #14
0
 def load_fcad_file(self, file_path):
     timer.start("loading shapes.fcad")
     self._shapes = ShapeFile.read_fcad_file(file_path)
 
     if len(self._shapes):
         def generator_function(points):
             for i, obj in enumerate(points):
                 if obj == None: continue
                 yield (i, self._styler.get_bbox(fshape.Shape.decompress(obj)), obj)
         self._index_rtree = Rtree(generator_function(self._shapes))
     timer.end("loading shapes.fcad")
Example #15
0
    class WayIndex:
        def __init__(self, ways):
            self.max_way_id = 0
            self.way_idx_mapping = {}
            self.idx = Rtree()
            for way in ways:
                self.add(way)

        def add(self, way):
            self.idx.add(id=self.max_way_id, coordinates=way.get_bbox(), 
                         obj=way.id)
            self.way_idx_mapping[way.id] = self.max_way_id
            self.max_way_id += 1

        def delete(self, way):
            self.idx.delete(id=self.way_idx_mapping[way.id],
                            coordinates=way.get_bbox())
            way_ids = map(lambda way: way.object, 
                          wayidx.idx.intersection(way.get_bbox(), 
                                                  objects=True))
Example #16
0
 def __init__(self, config_filename):
     self.index = Rtree()
     
     # get children from yaml file
     config_str = open(config_filename).read()
     print config_str
     self.children = yaml.load( config_str )
     
     # index children according to their bounding box
     for i, child in enumerate(self.children):
         self.index.add(i, child['bounds'])
Example #17
0
 def load_pickle(self, file_path):
     timer.start("loading shapes.p")
     if os.path.exists(file_path):
         self._shapes = pickle.load(open(file_path, "rb"))
         
         if len(self._shapes):
             def generator_function(points):
                 for i, obj in enumerate(points):
                     if obj == None: continue
                     yield (i, self._styler.get_bbox(fshape.Shape.decompress(obj)), obj)
             self._index_rtree = Rtree(generator_function(self._shapes))
     timer.end("loading shapes.p")
Example #18
0
    def __init__(self, all_trips):
        # trips
        self.all_trips = all_trips

        # cluster seeds
        self.cluster_seeds = {}
        self.cluster_seed_id = 0
        self.cluster_seed_index = Rtree()

        # graph edges
        self.graph_edges = {}  # indexed by "edge id"
        self.graph_edge_id = 0
        self.graph_edge_lookup = {}  # indexed by "location1_id,location2_id"
Example #19
0
class SampleSpace(object):
    def __init__(self):
        self._index = Rtree()
        self._locations = []
        self._values = []

    def __setitem__(self, location, value):
        i = len(self._locations)

        self._locations.append(location)
        self._values.append(value)
        self._index.add(i, self._locations[i])

    def __getitem__(self, location):
        js = list(self._index.nearest(location, 3))
        if len(js) == 0:
            return 0

        if len(js) == 1:
            return self._values[js[0]]

        ds = [sqrt(sum([(self._locations[j][i]-location[i])**2 for i in range(2)]))
              for j in js]

        for i in range(len(js)):
            if ds[i] == 0:
                return self._values[js[i]]

        R = max(ds)
        nums = [((R - d)/(R * d))**2 for d in ds]
        den = sum(nums)

        ws = [num/den for num in nums]

        return sum([self._values[js[i]] * ws[i] for i in range(len(js))])

    def __iter__(self):
        for i in range(len(self._values)):
            yield self._locations[i], self._values[i]
Example #20
0
 def _build_trip_edge_index(self):
     sys.stdout.write("\nBuilding trip edge index for clarification algorithm... ")
     sys.stdout.flush()
     
     # storage for trip edge index
     trip_edge_index = Rtree()
     
     # iterate through all trip edges
     for trip_edge in self.trip_edges.values():
         
         # determine trip edge minx, miny, maxx, maxy values
         trip_edge_minx = min(trip_edge.in_node.longitude, trip_edge.out_node.longitude)
         trip_edge_miny = min(trip_edge.in_node.latitude, trip_edge.out_node.latitude)
         trip_edge_maxx = max(trip_edge.in_node.longitude, trip_edge.out_node.longitude)
         trip_edge_maxy = max(trip_edge.in_node.latitude, trip_edge.out_node.latitude)
         
         # insert trip edge into spatial index
         trip_edge_index.insert(trip_edge.id, (trip_edge_minx, trip_edge_miny, trip_edge_maxx, trip_edge_maxy))
     
     print "done."
     
     # return the trip edge index
     return trip_edge_index
Example #21
0
 def _find_intersection_nodes(self):
     
     # storage for intersection nodes
     intersection_nodes = []
     
     # spatial index for intersection nodes
     intersection_nodes_index = Rtree()
     
     # iterate through all nodes in map
     for curr_node in self.nodes.values():
         
         # set storage for current node's unique neighbors
         neighbors = set()
         
         # iterate through all in_nodes
         for in_node in curr_node.in_nodes:
             
             # add in_node to neighbors set
             neighbors.add(in_node)
         
         # iterate through all out_nodes
         for out_node in curr_node.out_nodes:
             
             # add out_node to neighbors set
             neighbors.add(out_node)
         
         # if current node has more than 2 neighbors
         if (len(neighbors) > 2):
             
             # add current node to intersection nodes list
             intersection_nodes.append(curr_node)
             
             # add current node to intersection nodes index
             intersection_nodes_index.insert(curr_node.id, (curr_node.longitude, curr_node.latitude))
     
     # return intersection nodes and index
     return (intersection_nodes, intersection_nodes_index)
Example #22
0
 def clear(self):
     self.backward.clear()
     props = self.rtree.properties
     if props.storage == RT_Disk:
         self.rtree.close()
         fname = props.filename
         try:
             os.unlink('%s.%s' % (fname, props.dat_extension))
         except OSError:
             pass
         try:
             os.unlink('%s.%s' % (fname, props.idx_extension))
         except OSError:
             pass
     self.rtree = Rtree(*self.rtree_args)
Example #23
0
 def __init__(self, dbname,overwrite=False,rtree_index=True):
     if overwrite:
         try:
             os.remove( dbname )
         except OSError:
             pass
         
     self.conn = sqlite3.connect(dbname)
     
     if rtree_index:
         self.index = Rtree( dbname )
     else:
         self.index = None
     
     if overwrite:
         self.setup()
Example #24
0
    def __init__(self, srs, geom_type, fields, values, shapes):
        """ Use load() to call this constructor.
        """
        self.srs = srs
        self.fields = fields
        self.geom_type = geom_type
        self.values = values
        self.shapes = shapes

        # this will be changed later
        self.tolerance = 0
        
        # guid, src1_id, src2_id, line_id, x1, y1, x2, y2
        
        db = connect(':memory:').cursor()
        
        db.execute("""CREATE table segments (
                        
                        -- global identifier for this segment
                        guid    INTEGER PRIMARY KEY AUTOINCREMENT,
        
                        -- identifiers for source shape or shapes for shared borders
                        src1_id INTEGER,
                        src2_id INTEGER,
                        
                        -- global identifier for this line
                        line_id INTEGER,
                        
                        -- start and end coordinates for this segment
                        x1      REAL,
                        y1      REAL,
                        x2      REAL,
                        y2      REAL,
                        
                        -- flag
                        removed INTEGER
        
                      )""")
        
        db.execute('CREATE INDEX segments_lines ON segments (line_id, guid)')
        db.execute('CREATE INDEX shape1_parts ON segments (src1_id)')
        db.execute('CREATE INDEX shape2_parts ON segments (src2_id)')
        
        self.db = db
        self.rtree = Rtree()
        self.memo_line = make_memo_line()
Example #25
0
   def __init__(self):
       """Initialise the class by creating an instance of each object."""
       self._ratio_index = (0.05, 0.1, 0.2, 0.5, 1, 2, 4, 8, 16, 32, 64) # pagal sita dydi turi kisti tasko atstumas nuo zoominimo centro
       self._zoom_level = self._ratio_index.index(4) # 0-dirbame su realiomis koordinatemis - kitur koordinates yra gaunamos atliekant dalyba... todel nera labai tikslios
       
       self._device_area = None # gtk.gdk.Rectangle()
       
       self._shapes = [] # shapes data
       self._index_rtree = Rtree() # shapes indexes in self._shapes
       
       self._offset = Point(0, 0) #- naudojamas ctx.translate() #device koordinates
 
       self._prj = GisProjection()
       self._styler = Styler(self)
       self._painter = Painter(self._styler)
       
       self._drag_to_center = True # jeigu norime kad resize metu (bus iskviestas set_device_area) butu iskvietsas center()
Example #26
0
    def r_tree(self):
        if not hasattr(self, '_r_tree'):

            # define properties
            p = r_treeIndex.Property()
            p.dimension = self.dim()
            p.variant = r_treeIndex.RT_Star
            index = np.concatenate((range(self.dim()), range(self.dim())))

            # Generator provides required point format
            def gen():
                for id, coord in self:
                    yield (id, coord[index], id)

            self._r_tree = Rtree(gen(), properties=p)

        return self._r_tree
Example #27
0
 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()
Example #28
0
 def __init__(self):
     self.nodes = {}  # indexed by node id
     self.edges = {}  # indexed by edge id
     self.intersections = {}  # indexed by node id
     self.node_spatial_index = Rtree()
     self.edge_spatial_index = Rtree()
     self.intersection_spatial_index = Rtree()
     self.edge_lookup_table = {}  # indexed by (in_node,out_node)
     self.edge_coords_lookup_table = {
     }  # indexed by (in_node.coords, out_node.coords)
     self.segments = {}  # indexed by segment id
     self.segment_lookup_table = {
     }  # indexed by (head_edge.in_node, tail_edge.out_node)
Example #29
0
class SpatialIndex(Persistent):

    def __init__(self, *args):
        self.rtree_args = args
        self.rtree = Rtree(*args)
        self.backward = IOBTree()

    def index_doc(self, docid, value):
        if docid in self.backward:
            self.unindex_doc(docid)
        self.backward[docid] = value
        self.rtree.add(docid, value, obj=docid)

    def unindex_doc(self, docid):
        value = self.backward.get(docid)
        if value is None:
            return
        self.rtree.delete(docid, value)
        del self.backward[docid]

    def apply(self, value):
        return [x.object for x in self.rtree.intersection(value, objects=True)]

    def clear(self):
        self.backward.clear()
        props = self.rtree.properties
        if props.storage == RT_Disk:
            self.rtree.close()
            fname = props.filename
            try:
                os.unlink('%s.%s' % (fname, props.dat_extension))
            except OSError:
                pass
            try:
                os.unlink('%s.%s' % (fname, props.idx_extension))
            except OSError:
                pass
        self.rtree = Rtree(*self.rtree_args)

    def count(self, value):
        return self.rtree.count(value)
Example #30
0
def read_dag_to_tree(all_hits):
    """create an rtree, using query as x, subject as y
    do this for all htis, then for each diag, do an intersection
    (+bbuffer) to find nearby 
    """
    gdxs = {}
    for i, sline in enumerate(open(all_hits)):
        if sline[0] == '#': continue
        line = sline[:-1].split("\t")
        chrs = tuple(sorted([line[0], line[4]]))
        # so save the index, which will return i when queried
        # and associate i with the text line vie the dict.
        if not chrs in gdxs: gdxs[chrs] = ({}, Rtree())
        q0, q1 = sorted(map(int, line[2:4]))
        s0, s1 = sorted(map(int, line[6:8]))
        assert q0 < q1 and s0 < s1
        gdxs[chrs][1].add(i, (q0, s0, q1, s1))

        gdxs[chrs][0][i] = sline

    return gdxs
Example #31
0
    def __init__(self, psql_conn_string, overwrite=False, rtree_index=True):
        self.conn = psycopg2.connect(psql_conn_string)


        c = self.conn.cursor()
        c.execute("select tablename from pg_tables where schemaname='public'" )
        tables = c.fetchall()

        for t in ( 'osm_nodes', 'osm_ways' ):
            if (t,) not in tables:
                overwrite = True

        c.close()

        if overwrite:
            self.setup()

        if rtree_index:
            self.index = Rtree()
            self.index_endnodes()
        else:
            self.index = None
Example #32
0
    def add_random_points(self, number, area, generator=True):
        """Kai generator=False - sunaudoja maziau atminties ikrovimo metu, bet trunka gerokai leciau
        """
        self._shapes = []
        timer.start("Adding random data")

        from random import randint
        for x in range(0, number):
            color = 65536 * randint(0,255) + 256 * randint(0,255) + randint(0,255) # RGBint
            x, y = randint(2, area.width), randint(2, area.height)

            if not generator: # darysime rtree.add kiekvienam taskui atskirai
                self.add(fshape.Shape(1, Point(x, y), color=color))
            else:
                self._shapes.append((1, color, x, y))
        
        if generator:
            def generator_function(points):
                for i, obj in enumerate(points):
                    yield (i, (obj[2], obj[3], obj[2], obj[3]), obj)
            self._index_rtree = Rtree(generator_function(self._shapes))
        
        timer.end("Adding random data")
Example #33
0
 def to_directed(self, as_view=False):
     """
     Convert undirected road network to directed road network
     new edge will have new eid, and each original edge will have two edge with reversed coords
     :return:
     """
     assert as_view is False, "as_view is not supported"
     avail_eid = max([eid for u, v, eid in self.edges.data(data='eid')]) + 1
     g = nx.DiGraph()
     edge_spatial_idx = Rtree()
     edge_idx = {}
     # add nodes
     for n, data in self.nodes(data=True):
         # when data=True, it means will data=node's attributes
         new_data = copy.deepcopy(data)
         g.add_node(n, **new_data)
     # add edges
     for u, v, data in self.edges(data=True):
         mbr = MBR.cal_mbr(data['coords'])
         # add forward edge
         forward_data = copy.deepcopy(data)
         g.add_edge(u, v, **forward_data)
         edge_spatial_idx.insert(
             forward_data['eid'],
             (mbr.min_lng, mbr.min_lat, mbr.max_lng, mbr.max_lat))
         edge_idx[forward_data['eid']] = (u, v)
         # add backward edge
         backward_data = copy.deepcopy(data)
         backward_data['eid'] = avail_eid
         avail_eid += 1
         backward_data['coords'].reverse()
         g.add_edge(v, u, **backward_data)
         edge_spatial_idx.insert(
             backward_data['eid'],
             (mbr.min_lng, mbr.min_lat, mbr.max_lng, mbr.max_lat))
         edge_idx[backward_data['eid']] = (v, u)
     print('# of nodes:{}'.format(g.number_of_nodes()))
     print('# of edges:{}'.format(g.number_of_edges()))
     return RoadNetwork(g, edge_spatial_idx, edge_idx)
Example #34
0
from flask import redirect, request, current_app, jsonify
import psycopg2
import psycopg2.extras
from collections import defaultdict
import os
from itertools import groupby
from shapely.ops import cascaded_union
from shapely.geometry import mapping, asShape
from shapely import speedups
import geo_utils
import vote_utils
from rtree import Rtree
from shapely.geometry import asShape
import geojson

index = Rtree()
hoodIndex = Rtree()

conn = psycopg2.connect("dbname='gis' user='******' host='localhost' password='******'")
cur = conn.cursor()

def processArea(areaid):
  hoodDict = {}
  (hoods, id_to_label) = geo_utils.getNeighborhoodsByArea(conn, areaid, None)
  for (id, shape) in hoods.iteritems():
    hoodIndex.add(int(id), shape.bounds)
    hoodDict[int(id)] = shape
  
  (rows, voteDict) = vote_utils.getVotes(conn, areaid, None)

  bestVoteDict = {}
Example #35
0
def mod_kruskal(G, subgraphs=None, rtree=None):

    """
    algorithm to compute the euclidean minimum spanning forest of nodes in
    GeoGraph G with 'budget' based restrictions on edges

    Uses a modified version of Kruskal's algorithm

    NOTE:  subgraphs is modified as a side-effect...may remove in future
        (useful for testing right now)

    Args:
        G:  GeoGraph of nodes to be connected if appropriate
            Nodes should have 'budget' attribute

        subgraphs:  UnionFind data structure representing existing network's
            connected components AND the 'fake' nodes projected onto it.  This
            is the basis for the agglomerative nearest neighbor approach in
            this algorithm.

            NOTE:  ONLY the existing networks components are represented in
            the subgraphs argument.  The nodes in G will be added within
            this function

        rtree:  RTree based index of existing network

    Returns:
        GeoGraph: representing minimum spanning forest of G subject to the
            budget based restrictions
    """

    # special case (already MST)
    if G.number_of_nodes() < 2:
        return G

    def is_fake(node):
        """
        Tests whether the node is a projection on the existing grid,
        using its MV
        """
        return subgraphs.budget[node] == np.inf

    # handy to have coords array
    coords = np.row_stack(G.coords.values())

    if subgraphs is None:
        assert rtree is not None, \
            "subgraphs (disjoint set) required when rtree is passed"

        rtree = Rtree()

        # modified to handle queues, children, mv
        subgraphs = UnionFind()

    # add nodes and budgets from G to subgraphs as components
    for node in G.nodes():
        subgraphs.add_component(node, budget=G.node[node]['budget'])

    # get fully connected graph
    g = G.get_connected_weighted_graph()

    # edges in MSF
    Et = []
    # connect the shortest safe edge until all edges have been tested
    # at which point, we have made all possible connections
    for u, v, w in sorted(g.edges(data=True), key=lambda x: x[2]['weight']):
        # if doesn't create cycle
        # and subgraphs have enough MV
        # and we're not connecting 2 fake nodes
        # then allow the connection
        w = w['weight']
        if subgraphs[u] != subgraphs[v] and \
           (subgraphs.budget[subgraphs[u]] >= w or is_fake(u)) and \
           (subgraphs.budget[subgraphs[v]] >= w or is_fake(v)) and \
           not (is_fake(u) and is_fake(v)):

            # doesn't create cycles from line segment intersection
            invalid_edge, intersections = \
                line_subgraph_intersection(subgraphs, rtree,
                                           coords[u], coords[v])

            if not invalid_edge:
                # edges should not intersect a subgraph more than once
                assert(filter(lambda n: n > 1,
                       intersections.values()) == [])

                # merge the subgraphs
                subgraphs.union(u, v, w)

                # For all intersected subgraphs update the mv to that
                # created by the edge intersecting them
                map(lambda (n, _): subgraphs.union(u, n, 0),
                    filter(lambda (n, i): i == 1 and
                    subgraphs[n] != subgraphs[u],
                    intersections.iteritems()))

                # index the newly added edge
                box = make_bounding_box(coords[u], coords[v])

                # Object is (u.label, v.label), (u.coord, v.coord)
                rtree.insert(hash((u, v)), box,
                             obj=((u, v), (coords[u], coords[v])))
                Et += [(u, v, {'weight': w})]

    # create new GeoGraph with results
    result = G.copy()
    result.coords = G.coords
    result.remove_edges_from(result.edges())
    result.add_edges_from(Et)
    return result
'''
@author Ben
@file rtree_area_example.py
In this example we will compare Shapely AGAINST RTREE for performance

NOTE: to get this to work I had to install libspatialindex 1.5 from source
and then:
export LD_LIBRARY_PATH=/usr/local/lib

'''

import random, os, sys, time, numpy

from rtree import Rtree
# instantiate the Rtree class
RtreeIndex = Rtree()

import random, os, sys, time, numpy
from shapely import *
from shapely.geometry import Point

filename = 'rtree_radius_search.png'
numberOfPoints = 50000
gridWidth = 10000
gridHeight = 10000
shapePoints = []

circleRadius = random.randint(500, 1500)
circleX = random.randint(0, gridWidth)
circleY = random.randint(0, gridHeight)
Example #37
0
def api_root():
    ''' This is the root of the webservice, upon successful authentication a text will be displayed in the browser '''
    try:
        projectid = request.args.get('projectid')
        diagramid = request.args.get('diagramid')
        apitoken = request.args.get('apitoken')
    except KeyError as ke:
        msg = json.dumps({
            "message":
            "Could not parse Projectid, Diagram ID or API Token ID. One or more of these were not found in your JSON request."
        })
        return Response(msg, status=400, mimetype='application/json')

    if projectid and diagramid and apitoken:
        myAPIHelper = GeodesignHub.GeodesignHubClient(
            url=config.apisettings['serviceurl'],
            project_id=projectid,
            token=apitoken)
        myGridGenerator = GridGenerator()
        myDiagramDecomposer = DiagramDecomposer()

        r = myAPIHelper.get_diagram(int(diagramid))

        try:
            assert r.status_code == 200
        except AssertionError as ae:
            print("Invalid reponse %s" % ae)
        else:
            op = json.loads(r.text)
            diaggeoms = op['geojson']
            sysid = op['sysid']
            desc = op['description']
            projectorpolicy = op['type']
            fundingtype = 'o'
            geoms, bounds = myDiagramDecomposer.processGeoms(diaggeoms)
            grid, allbounds = myGridGenerator.generateGrid(bounds)

        gridRTree = Rtree()
        for boundsid, bounds in allbounds.items():
            gridRTree.insert(boundsid, bounds)

        choppedgeomsandareas = []
        choppedgeoms = []
        totalarea = 0
        for curgeom in geoms:
            curbounds = curgeom.bounds
            igridids = list(gridRTree.intersection(curbounds))

            for curintersectid in igridids:
                gridfeat = grid[curintersectid]
                ifeat = curgeom.intersection(gridfeat)
                ifeatarea = ifeat.area
                totalarea += ifeatarea
                ele = {'area': ifeatarea, 'feature': ifeat}
                choppedgeoms.append(ele)

        sortedgeomsandareas = sorted(choppedgeoms, key=lambda k: k['area'])

        tenpercent = ((totalarea * 10) / 100)
        thirtypercent = ((totalarea * 30) / 100)
        seventypercent = ((totalarea * 70) / 100)
        # print totalarea, tenpercent, thirtypercent, seventypercent
        a = 0
        tenpercentfeats = {"type": "FeatureCollection", "features": []}
        twentypercentfeats = {"type": "FeatureCollection", "features": []}
        seventypercentfeats = {"type": "FeatureCollection", "features": []}

        for cursortedgeom in sortedgeomsandareas:
            cf = {}
            j = json.loads(
                shapelyHelper.export_to_JSON(cursortedgeom['feature']))
            cf['type'] = 'Feature'
            cf['properties'] = {}
            cf['geometry'] = j
            if a < tenpercent:
                tenpercentfeats['features'].append(cf)
            elif a > tenpercent and a < thirtypercent:
                twentypercentfeats['features'].append(cf)
            else:
                seventypercentfeats['features'].append(cf)
            a += float(cursortedgeom['area'])

        opdata = [{
            'gj': tenpercentfeats,
            'desc': "10% " + desc
        }, {
            'gj': twentypercentfeats,
            'desc': "20% " + desc
        }, {
            'gj': seventypercentfeats,
            'desc': "70% " + desc,
            "fundingtype": fundingtype
        }]
        alluploadmessages = []
        for curopdata in opdata:
            print(json.dumps(curopdata['gj']))
            # upload = myAPIHelper.post_as_diagram(geoms = json.dumps(curopdata['gj']), projectorpolicy= projectorpolicy,featuretype = 'polygon', description= curopdata['desc'], sysid = sysid)
            # alluploadmessages.append(json.loads(upload.text))

        msg = json.dumps({
            "message": "Diagrams have been uploaded",
            "uploadstatus": alluploadmessages
        })
        return Response(msg, status=400, mimetype='application/json')

    else:

        msg = json.dumps({
            "message":
            "Could not parse Project ID, Diagram ID or API Token ID. One or more of these were not found in your JSON request."
        })
        return Response(msg, status=400, mimetype='application/json')
Example #38
0
'''
RTREE is a spatial index that answers the question ->
What points are within this 2-dimensional box.
RTREE helps us speed up other calculations by only considering legitimate
objects for more complex comparisons.

'''

from rtree import Rtree
# instantiate the Rtree class
idx = Rtree()
# create a selection boundary (2d bounding box)
minx, miny, maxx, maxy = (0.0, 0.0, 1.0, 1.0)
# add an item to the index
idx.add(0, (minx, miny, maxx, maxy))
# Intersect another bounding box with the original bounding box.
list(idx.intersection((1.0, 1.0, 2.0, 2.0)))
#[0L]
# Point out the accuracy of the spatial calculation
list(idx.intersection((1.0000001, 1.0000001, 2.0, 2.0)))
#[]

#add another item to the index. - show EXACT dimensiion matching
index.add(id=id, (left, bottom, right, top))
object = [n for n in index.intersection((left, bottom, right, top))]
#[id]

# Find nearest object / bounding box
idx.add(1, (minx, miny, maxx, maxy))
list(idx.nearest((1.0000001, 1.0000001, 2.0, 2.0), 1))
#[0L, 1L]
Example #39
0
 def delete(self, id_, coords):
     with threading.RLock():
         Rtree.delete(self, id_, coords)            
Example #40
0
class StreetMap:
    def __init__(self):
        self.nodes = {}  # indexed by node id
        self.edges = {}  # indexed by edge id
        self.intersections = {}  # indexed by node id
        self.node_spatial_index = Rtree()
        self.edge_spatial_index = Rtree()
        self.intersection_spatial_index = Rtree()
        self.edge_lookup_table = {}  # indexed by (in_node,out_node)
        self.edge_coords_lookup_table = {
        }  # indexed by (in_node.coords, out_node.coords)
        self.segments = {}  # indexed by segment id
        self.segment_lookup_table = {
        }  # indexed by (head_edge.in_node, tail_edge.out_node)

    def load_osmdb(self, osmdb_filename):

        # connect to OSMDB
        conn = sqlite3.connect(osmdb_filename)

        # grab cursor
        cur = conn.cursor()

        # output that we are loading nodes
        sys.stdout.write("\nLoading nodes... ")
        sys.stdout.flush()

        # execute query on nodes table
        query_iter = cur.execute("select id, lat, lon from nodes")
        #        query_result = cur.fetchall()

        # iterate through all query results
        for id, lat, lon in query_iter:

            # create and store node in nodes dictionary
            self.nodes[int(id)] = Node(float(lat), float(lon), int(id))

        print "done."

        # output that we are loading edges
        sys.stdout.write("Loading edges... ")
        sys.stdout.flush()

        # execute query on ways table
        query_iter = cur.execute("select id, tags, nds from ways")
        #        query_result = cur.fetchall()

        # storage for nodes used in valid edges
        valid_edge_nodes = {}  # indexed by node id

        # iterate through all query results
        for id, tags, nodes in query_iter:

            # grab tags associated with current way
            way_tags_dict = eval(tags)

            # if current way is a valid highway
            if ('highway' in way_tags_dict.keys()
                    and self._valid_highway_edge(way_tags_dict['highway'])):

                # grab all nodes that compose this way
                way_nodes_list = eval(nodes)

                # iterate through list of way nodes
                for i in range(1, len(way_nodes_list)):

                    # grab in_node from nodes dictionary
                    in_node = self.nodes[int(way_nodes_list[i - 1])]

                    # grab out_node from nodes dictionary
                    out_node = self.nodes[int(way_nodes_list[i])]

                    # create edge_id based on way id
                    edge_id = int(str(id) + str(i - 1) + "000000")

                    # if either node on the edge is valid
                    if (
                            True
                    ):  #self._valid_node(in_node) or self._valid_node(out_node)):

                        # create and store edge in edges dictionary
                        self.edges[int(edge_id)] = Edge(
                            in_node, out_node, int(edge_id))

                        # store in_node in out_node's in_nodes list
                        if (in_node not in out_node.in_nodes):
                            out_node.in_nodes.append(in_node)

                        # store out_node in in_node's out_nodes list
                        if (out_node not in in_node.out_nodes):
                            in_node.out_nodes.append(out_node)

                        # if edge is bidirectional
                        if ('oneway' not in way_tags_dict.keys()):

                            # create new symmetric edge id
                            symmetric_edge_id = int(str(edge_id / 10) + "1")

                            # create and store symmetric edge in edges dictionary
                            self.edges[int(symmetric_edge_id)] = Edge(
                                out_node, in_node, int(symmetric_edge_id))

                            # store in_node in out_node's out_nodes list
                            if (in_node not in out_node.out_nodes):
                                out_node.out_nodes.append(in_node)

                            # store out_node in in_node's in_nodes list
                            if (out_node not in in_node.in_nodes):
                                in_node.in_nodes.append(out_node)

                        # store in_node in valid_edge_nodes dictionary
                        if (in_node.id not in valid_edge_nodes.keys()):
                            valid_edge_nodes[in_node.id] = in_node

                        # store out_node in valid_edge_nodes dictionary
                        if (out_node.id not in valid_edge_nodes.keys()):
                            valid_edge_nodes[out_node.id] = out_node

        print "done."

        # close connection to OSMDB
        conn.close()

        # replace all nodes with valid edge nodes
        self.nodes = valid_edge_nodes

        # index nodes
        self._index_nodes()

        # index edges
        self._index_edges()

        # find and index intersections
        self._find_and_index_intersections()

        # output map statistics
        print "Map has " + str(len(self.nodes)) + " nodes, " + str(
            len(self.edges)) + " edges and " + str(len(
                self.intersections)) + " intersections."

    def load_graphdb(self, grapdb_filename):

        # connect to graph database
        conn = sqlite3.connect(grapdb_filename)

        # grab cursor
        cur = conn.cursor()

        # output that we are loading nodes
        sys.stdout.write("\nLoading nodes... ")
        sys.stdout.flush()

        # execute query on nodes table
        cur.execute("select id, latitude, longitude, weight from nodes")
        query_result = cur.fetchall()

        # iterate through all query results
        for id, latitude, longitude, weight in query_result:

            # create and store node in nodes dictionary
            self.nodes[id] = Node(latitude, longitude, id, weight)

        print "done."

        # output that we are loading edges
        sys.stdout.write("Loading edges... ")
        sys.stdout.flush()

        # execute query on ways table
        cur.execute("select id, in_node, out_node, weight from edges")
        query_result = cur.fetchall()

        # storage for nodes used in valid edges
        valid_edge_nodes = {}  # indexed by node id

        # iterate through all query results
        for id, in_node_id, out_node_id, weight in query_result:

            # grab in_node from nodes dictionary
            in_node = self.nodes[in_node_id]

            # grab out_node from nodes dictionary
            out_node = self.nodes[out_node_id]

            # if either node on the edge is valid
            if (True
                ):  #self._valid_node(in_node) or self._valid_node(out_node)):

                # create and store edge in edges dictionary
                self.edges[id] = Edge(in_node, out_node, id, weight)

                # store in_node in out_node's in_nodes list
                if (in_node not in out_node.in_nodes):
                    out_node.in_nodes.append(in_node)

                # store out_node in in_node's out_nodes list
                if (out_node not in in_node.out_nodes):
                    in_node.out_nodes.append(out_node)

                # store in_node in valid_edge_nodes dictionary
                if (in_node.id not in valid_edge_nodes.keys()):
                    valid_edge_nodes[in_node.id] = in_node

                # store out_node in valid_edge_nodes dictionary
                if (out_node.id not in valid_edge_nodes.keys()):
                    valid_edge_nodes[out_node.id] = out_node

        # execute query on segments table
        cur.execute("select id, edge_ids from segments")
        query_result = cur.fetchall()

        for id, edge_ids in query_result:
            segment_edges = map(lambda edge_id: self.edges[edge_id],
                                eval(edge_ids))
            self.segments[id] = Segment(id, segment_edges)

            self.segment_lookup_table[(
                self.segments[id].head_edge.in_node,
                self.segments[id].tail_edge.out_node)] = self.segments[id]

            for segment_edge in segment_edges:
                segment_edge.segment = self.segments[id]


#                self.segment_lookup_table[segment_edge.id] = self.segments[id]

# execute query on intersections table
        cur.execute("select node_id from intersections")
        query_result = cur.fetchall()

        for node_id in query_result:
            self.intersections[node_id[0]] = self.nodes[node_id[0]]

        try:
            cur.execute(
                "select transition_segment, from_segment, to_segment from transitions"
            )
            query_result = cur.fetchall()
            self.transitions = {}
            for transition_segment, from_segment, to_segment in query_result:
                self.transitions[transition_segment] = (from_segment,
                                                        to_segment)
        except:
            print "Got an error reading "

        print "done."

        # close connection to graph db
        conn.close()

        # replace all nodes with valid edge nodes
        self.nodes = valid_edge_nodes

        # index nodes
        self._index_nodes()

        # index edges
        self._index_edges()

        # find and index intersections
        #self._find_and_index_intersections()

        # output map statistics
        print "Map has " + str(len(self.nodes)) + " nodes, " + str(
            len(self.edges)) + " edges, " + str(len(
                self.segments)) + " segments and " + str(
                    len(self.intersections)) + " intersections."

    def load_shapedb(self, shapedb_filename):

        # connect to graph database
        conn = sqlite3.connect(shapedb_filename)

        # grab cursor
        cur = conn.cursor()

        # execute query to find all shape ids
        cur.execute("select distinct shape_id from shapes")

        # output that we are loading nodes and edges
        sys.stdout.write("\nLoading nodes and edges... ")
        sys.stdout.flush()

        # storage for shape specific edges
        self.shape_edges = {}  # indexed by shape_id

        # storage for node id
        node_id = 0

        # iterate through all shape ids
        for shape_id in cur.fetchall():

            # grab shape id
            shape_id = shape_id[0]

            # if route is a bus route
            if (shape_id == "0" or shape_id == "11" or shape_id == "15"
                    or shape_id == "41" or shape_id == "65"
                    or shape_id == "22"):

                # execute query to find all shape points
                cur.execute(
                    "select shape_pt_lat, shape_pt_lon from shapes where shape_id='"
                    + str(shape_id) + "' order by shape_pt_sequence asc")

                # amend shape id
                if (shape_id == "0"):
                    shape_id = "10000000"
                elif (shape_id == "11"):
                    shape_id = "10000011"
                elif (shape_id == "41"):
                    shape_id = "10000041"
                elif (shape_id == "15"):
                    shape_id = "10000015"
                elif (shape_id == "65"):
                    shape_id = "10000065"
                elif (shape_id == "22"):
                    shape_id = "10000022"

                # storage for first node
                first_node = None

                # storage for previous node
                prev_node = None

                # create list for this shape's edges
                self.shape_edges[shape_id] = []

                # iterate through all shape points
                for shape_pt_lat, shape_pt_lon in cur.fetchall():

                    # create new node
                    curr_node = Node(shape_pt_lat, shape_pt_lon, node_id)

                    # store first node
                    if (first_node is None):
                        first_node = curr_node

                    # increment node id
                    node_id += 1

                    # add shape id to node
                    curr_node.shape_id = shape_id

                    # store new node in nodes dictionary
                    self.nodes[node_id] = curr_node

                    # if there exists a previous node
                    if (prev_node is not None):

                        # create edge id
                        edge_id = int(
                            str(shape_id) + str(prev_node.id) +
                            str(curr_node.id))

                        # create new edge
                        curr_edge = Edge(prev_node, curr_node, edge_id)

                        # add shape id to edge
                        curr_edge.shape_id = shape_id

                        # store new edge in edges dictionary
                        self.edges[edge_id] = curr_edge

                        # store new edge in shape edges dictionary
                        self.shape_edges[shape_id].append(curr_edge)

                        # store previous node in current node's in_nodes list
                        curr_node.in_nodes.append(prev_node)

                        # store current node in previous node's out_nodes list
                        prev_node.out_nodes.append(curr_node)

                    # update previous node
                    prev_node = curr_node

                # create edge id for last edge
                edge_id = int(
                    str(shape_id) + str(prev_node.id) + str(first_node.id))

                # create new edge
                curr_edge = Edge(prev_node, first_node, edge_id)

                # add shape id to edge
                curr_edge.shape_id = shape_id

                # store new edge in edges dictionary
                self.edges[edge_id] = curr_edge

                # store new edge in shape edges dictionary
                self.shape_edges[shape_id].append(curr_edge)

                # store previous node in first node's in_nodes list
                first_node.in_nodes.append(prev_node)

                # store first node in previous node's out_nodes list
                prev_node.out_nodes.append(first_node)

        print "done."

        # close connection to gtfs db
        conn.close()

        # index nodes
        self._index_nodes()

        # index edges
        self._index_edges()

        # find and index intersections
        self._find_and_index_intersections()

        # output map statistics
        print "Map has " + str(len(self.nodes)) + " nodes, " + str(
            len(self.edges)) + " edges and " + str(len(
                self.intersections)) + " intersections."

    def _index_nodes(self):

        # output that we are indexing nodes
        sys.stdout.write("Indexing nodes... ")
        sys.stdout.flush()

        # iterate through all nodes
        for curr_node in self.nodes.values():

            # insert node into spatial index
            self.node_spatial_index.insert(
                curr_node.id, (curr_node.longitude, curr_node.latitude))

        print "done."

    def _index_edges(self):

        # output that we are indexing edges
        sys.stdout.write("Indexing edges... ")
        sys.stdout.flush()

        # iterate through all edges
        for curr_edge in self.edges.values():

            # determine current edge minx, miny, maxx, maxy values
            curr_edge_minx = min(curr_edge.in_node.longitude,
                                 curr_edge.out_node.longitude)
            curr_edge_miny = min(curr_edge.in_node.latitude,
                                 curr_edge.out_node.latitude)
            curr_edge_maxx = max(curr_edge.in_node.longitude,
                                 curr_edge.out_node.longitude)
            curr_edge_maxy = max(curr_edge.in_node.latitude,
                                 curr_edge.out_node.latitude)

            # insert current edge into spatial index
            self.edge_spatial_index.insert(curr_edge.id,
                                           (curr_edge_minx, curr_edge_miny,
                                            curr_edge_maxx, curr_edge_maxy))

            # insert current edge into lookup table
            self.edge_lookup_table[(curr_edge.in_node,
                                    curr_edge.out_node)] = curr_edge
            self.edge_coords_lookup_table[(
                curr_edge.in_node.coords(),
                curr_edge.out_node.coords())] = curr_edge

        # iterate through all edges
        for edge in self.edges.values():

            # iterate through all out edges
            for out_node_neighbor in edge.out_node.out_nodes:

                # add out edge to out edges list
                edge.out_edges.append(
                    self.edge_lookup_table[(edge.out_node, out_node_neighbor)])

            # iterate through all in edges
            for in_node_neighbor in edge.in_node.in_nodes:

                # add in edge to in edges list
                edge.in_edges.append(self.edge_lookup_table[(in_node_neighbor,
                                                             edge.in_node)])

        print "done."

    def _find_and_index_intersections(self):

        # output that we are finding and indexing intersections
        sys.stdout.write("Finding and indexing intersections... ")
        sys.stdout.flush()

        # find intersection nodes and index
        (intersection_nodes,
         intersection_nodes_index) = self._find_intersection_nodes()

        # storage for intersection nodes already placed in intersections
        placed_intersection_nodes = set()

        # define longitude/latitude offset for bounding box
        lon_offset = ((intersection_size / 2.0) / METERS_PER_DEGREE_LONGITUDE)
        lat_offset = ((intersection_size / 2.0) / METERS_PER_DEGREE_LATITUDE)

        # storage for intersection id
        intersection_id = 0

        # iterate through intersection nodes
        for intersection_node in intersection_nodes:

            # if the intersection node has not yet been placed
            if (intersection_node not in placed_intersection_nodes):

                # create bounding box
                bounding_box = (intersection_node.longitude - lon_offset,
                                intersection_node.latitude - lat_offset,
                                intersection_node.longitude + lon_offset,
                                intersection_node.latitude + lat_offset)

                # find intersection node ids within bounding box
                intersection_node_ids = intersection_nodes_index.intersection(
                    bounding_box)

                # get intersection nodes
                intersection_nodes = map(self._get_node, intersection_node_ids)

                # add intersection nodes to placed set
                placed_intersection_nodes.update(intersection_nodes)

                # create new intersection
                new_intersection = Intersection(intersection_id,
                                                intersection_nodes)

                # increment intersection id
                intersection_id += 1

                # add new intersection to intersections list
                self.intersections[new_intersection.id] = new_intersection

                # insert new intersection into spatial index
                self.intersection_spatial_index.insert(
                    new_intersection.id,
                    (new_intersection.longitude, new_intersection.latitude))

        print "done."

    def _get_node(self, node_id):

        # return node from dictionary
        return self.nodes[node_id]

    def _find_intersection_nodes(self):

        # storage for intersection nodes
        intersection_nodes = []

        # spatial index for intersection nodes
        intersection_nodes_index = Rtree()

        # iterate through all nodes in map
        for curr_node in self.nodes.values():

            # set storage for current node's unique neighbors
            neighbors = set()

            # iterate through all in_nodes
            for in_node in curr_node.in_nodes:

                # add in_node to neighbors set
                neighbors.add(in_node)

            # iterate through all out_nodes
            for out_node in curr_node.out_nodes:

                # add out_node to neighbors set
                neighbors.add(out_node)

            # if current node has more than 2 neighbors
            if (len(neighbors) > 2):

                # add current node to intersection nodes list
                intersection_nodes.append(curr_node)

                # add current node to intersection nodes index
                intersection_nodes_index.insert(
                    curr_node.id, (curr_node.longitude, curr_node.latitude))

        # return intersection nodes and index
        return (intersection_nodes, intersection_nodes_index)

    def _valid_node(self, node):

        # if node falls inside the designated bounding box
        if ((node.latitude >= 41.8619 and node.latitude <= 41.8842) and
            (node.longitude >= -87.6874 and node.longitude <= -87.6398)):

            return True
        else:
            return False

    def _valid_highway_edge(self, highway_tag_value):
        if ((highway_tag_value == 'primary')
                or (highway_tag_value == 'secondary')
                or (highway_tag_value == 'tertiary')
                or (highway_tag_value == 'residential')):

            return True
        else:
            return False

    def reset_node_visited_flags(self):

        # iterate through all nodes
        for node in self.nodes.values():

            # set node visited flag to False
            node.visited = False

    def reset_edge_visited_flags(self):

        # iterate through all edges
        for edge in self.edges.values():

            # set edge visited flag to False
            edge.visited = False

    def write_map_to_file(self, map_filename="map.txt"):

        # output that we are starting the writing process
        sys.stdout.write("\nWriting map to file... ")
        sys.stdout.flush()

        # open map file
        map_file = open(map_filename, 'w')

        # iterate through all map edges
        for curr_edge in self.edges.values():

            # output current edge to file
            map_file.write(
                str(curr_edge.in_node.latitude) + "," +
                str(curr_edge.in_node.longitude) + "\n")
            map_file.write(
                str(curr_edge.out_node.latitude) + "," +
                str(curr_edge.out_node.longitude) + "\n\n")

        # close map file
        map_file.close()

        print "done."

    def _distance(self, location1, location2):
        return spatialfunclib.distance(location1.latitude, location1.longitude,
                                       location2.latitude, location2.longitude)
Example #41
0
class Geometry(object):
    def __init__(self, wkb):
        self._wkb = wkb
        self._geom = None

    def geom(self):
        if not self._geom:
            self._geom = wkb.loads(self._wkb)
        return self._geom

    def __repr__(self):
        return self.geom().wkt

data_filename = sys.argv[1] + '.data'
index_filename = sys.argv[1] + '.data.idx'
tree = Rtree(sys.argv[1])

data_file = open(data_filename, 'r+')
index_file = open(index_filename, 'r+')

index_file.seek(0, os.SEEK_END)
index_length = index_file.tell()
index_file.seek(0)

data_file.seek(0, os.SEEK_END)
data_length = data_file.tell()
data_file.seek(0)

query = tuple([float(v) for v in sys.argv[2:6]])

print query
Example #42
0
        print >> sys.stderr, "Caching points, blocks, and names ..."
        pickle.dump((names, blocks, places), file(areaid + ".cache", "w"), -1)
    blocks = map(asShape, blocks)

points = []
place_list = set()
count = 0
for place_id, pts in places.items():
    count += 1
    print >> sys.stderr, "\rPreparing %d of %d places..." % (count,
                                                             len(places)),
    for pt in pts:
        place_list.add((len(points), pt + pt, None))
        points.append((place_id, Point(pt)))
print >> sys.stderr, "Indexing...",
index = Rtree(place_list)
print >> sys.stderr, "Done."


def score_block(polygon):
    centroid = polygon.centroid
    #prepared = prep(polygon)
    score = {}
    outside_samples = 0
    for item in index.nearest((centroid.x, centroid.y),
                              num_results=SAMPLE_SIZE):
        place_id, point = points[item]
        score.setdefault(place_id, 0.0)
        #if prepared.contains(point):
        #    score[place_id] += 1.0
        #else:
class Graph:
    def __init__(self, bus_trips):
        self.bus_trips = bus_trips
        self.graph_nodes = {}  # indexed by "location_id"
        self.graph_edge_id = 0
        self.graph_edges = {}  # indexed by "edge id"
        self.graph_edge_lookup = {}  # indexed by "location1_id,location2_id"
        self.graph_edge_index = Rtree()

    def generate_graph(self):
        print "Running graph generation algorithm..."

        # initialize trip counter
        trip_count = 1

        for trip in self.bus_trips:

            # initialize location counter
            location_count = 1

            # storage for previous node
            prev_node = None

            for location in trip.locations:
                sys.stdout.write("\rAnalyzing location " +
                                 str(location_count) + "/" +
                                 str(len(trip.locations)) + " for trip " +
                                 str(trip_count) + "/" +
                                 str(len(self.bus_trips)) + "... ")
                sys.stdout.flush()

                # find closest edges in graph to location
                closest_edges = self._find_closest_edges_in_graph(
                    location, 100)

                # flag variable for whether we merged location
                did_merge_location = False

                # iterate through candidate edge ids
                for candidate_edge_id in closest_edges:

                    # grab candidate edge from graph edge dictionary
                    candidate_edge = self.graph_edges[candidate_edge_id]

                    # determine whether we should merge with candidate edge
                    if (self._should_merge_location_with_edge(
                            location, candidate_edge) is True):

                        # merge location with edge, update previous node
                        prev_node = self._merge_location_with_edge(
                            location, candidate_edge, prev_node)

                        # update merge flag variable
                        did_merge_location = True

                        # no need to look at further edges, break out of candidate edges loop
                        break

                # if we did not merge the location with any edge
                if (did_merge_location is False):

                    # add location to graph
                    self._add_location_to_graph(location, prev_node)

                    # update previous node with current location
                    prev_node = location

                # increment location counter
                location_count += 1

            # done with current trip locations
            print "done."

            # increment trip counter
            trip_count += 1

        # write graph edges to file
        self._write_graph_edges_to_file()

        # create graph database
        self._output_graph_to_db()

    def _merge_location_with_edge(self, location, edge, prev_node):

        # get the edge node closest to the location
        edge_node = self._get_closest_edge_node(location, edge)

        # if prev_node is None
        if (prev_node is None):

            # increase volume of just this edge
            edge.volume += 1

        # if prev_node is not None
        else:

            # find path from prev_node to edge_node
            path = self._find_path(prev_node, edge_node, max_path_length)

            # if there was a path from prev_node to edge_node
            if (path is not None):

                # iterate through nodes in path
                for i in range(1, len(path)):

                    # grab in_node
                    in_node = path[i - 1]

                    # grab out_node
                    out_node = path[i]

                    # find corresponding graph edge
                    graph_edge = self._find_graph_edge(in_node, out_node)

                    # increment volume on edge
                    graph_edge.volume += 1

            # if there is no path from prev_node to edge_node
            else:

                # create a new graph edge between prev_node and edge_node
                self._create_graph_edge(prev_node, edge_node)

        # return the edge_node
        return edge_node

    def _get_closest_edge_node(self, location, edge):

        # if in_node distance is less than out_node distance
        if (self._distance(location, edge.in_node) < self._distance(
                location, edge.out_node)):

            # return the edge in_node
            return edge.in_node

        # otherwise, return the edge out_node
        return edge.out_node

    def _find_path(self, source, destination, max_length):

        # reset all node visited flags
        self._reset_node_visited_flags()

        # get a breath-first search path from source to destination
        path = self._bfs_path(source, destination)

        # if there is a path from source to destination
        if (path is not None):

            # and if the path length is less than or equal to the maximum length
            if (len(path) <= max_length):

                # return the path
                return path

        # otherwise, return None
        return None

    def _bfs_path(self, source, destination):

        # storage for breadth-first search parents
        bfs_parent = {}  # key is current node, value is parent node

        # source node has no breadth-first search parent
        bfs_parent[source] = None

        # node queue for breadth-first search
        bfs_queue = []

        # enqueue source node
        bfs_queue.append(source)

        # mark source node as visited
        source.visited = True

        # while the queue is not empty
        while (len(bfs_queue) > 0):

            # dequeue the first node in the queue
            curr_node = bfs_queue.pop(0)

            # if the current node is the destination
            if (curr_node is destination):

                # create storage for breadth-first search path
                bfs_path = []

                # add the current node to the breadth-first search path
                bfs_path.insert(0, curr_node)

                # grab the parent of the current node
                parent = bfs_parent[curr_node]

                # iterate through breadth-first search parents
                while (parent is not None):

                    # add the parent to the breadth-first search path
                    bfs_path.insert(0, parent)

                    # grab the next parent
                    parent = bfs_parent[parent]

                # return the breadth-first search path
                return bfs_path

            # if the current node is not the destination
            else:

                # iterate through the current node's out_nodes
                for out_node in curr_node.out_nodes:

                    # if the out_node has not been visited
                    if (out_node.visited is False):

                        # mark the out_node as visited
                        out_node.visited = True

                        # enqueue the out_node
                        bfs_queue.append(out_node)

                        # store curr_node as out_node's breadth-first search parent
                        bfs_parent[out_node] = curr_node

        # if we reached here, no path was found
        return None

    def _should_merge_location_with_edge(self, location, edge):

        # project location onto edge
        (location_projection, location_projection_fraction,
         location_projection_distance) = self._projection_onto_line(
             edge.in_node, edge.out_node, location)

        # if projection is not onto edge
        if (location_projection_fraction < 0.0
                or location_projection_fraction > 1.0):

            # we cannot merge location with edge
            return False

        # determine bearing difference between edge and location
        bearing_difference = math.cos(
            math.radians(
                self._path_bearing(edge.in_node, edge.out_node) -
                self._location_bearing(location)))

        # if location projection distance is less than 20 meters
        if (location_projection_distance < location_projection_distance_limit):

            # if bearing difference is less than 45 degrees
            if (bearing_difference > location_bearing_difference_limit):

                # merge location with edge
                return True

        # otherwise, do not merge location with edge
        return False

    def _add_location_to_graph(self, location, prev_node):

        # add an out_nodes list to location
        location.out_nodes = []

        # add an in_nodes list to location
        location.in_nodes = []

        # add a visited flag to location
        location.visited = False

        # add location to graph nodes list
        self.graph_nodes[location.id] = location

        # if prev_node is not None
        if (prev_node is not None):

            # create a new graph edge between prev_node and location
            self._create_graph_edge(prev_node, location)

    def _create_graph_edge(self, in_node, out_node):

        # see if we can find an existing graph edge with the same nodes
        existing_graph_edge = self._find_graph_edge(in_node, out_node)

        # if there is no existing graph edge with the same nodes
        if (existing_graph_edge is None):

            # create new graph edge object
            new_graph_edge = Edge(self.graph_edge_id, in_node, out_node)

            # add new graph edge to graph edge dictionary
            self.graph_edges[new_graph_edge.id] = new_graph_edge

            # add new graph edge to graph edge lookup dictionary
            self.graph_edge_lookup[str(in_node.id) + "," +
                                   str(out_node.id)] = new_graph_edge

            # add new graph edge to graph edges spatial index
            self._add_graph_edge_to_index(new_graph_edge)

            # increment graph edge id
            self.graph_edge_id += 1

            # store out_node in in_nodes's out_nodes list
            in_node.out_nodes.append(out_node)

            # store in_node in out_node's in_nodes list
            out_node.in_nodes.append(in_node)

    def _find_graph_edge(self, node1, node2):

        # generate edge lookup key
        edge_lookup_key = str(node1.id) + "," + str(node2.id)

        # if edge is in lookup table
        if (edge_lookup_key in self.graph_edge_lookup.keys()):

            # return the matching edge
            return self.graph_edge_lookup[edge_lookup_key]

        # if the edge wasn't in the lookup table
        return None

    def _add_graph_edge_to_index(self, graph_edge):

        # determine graph edge minx, miny, maxx, maxy values
        graph_edge_minx = min(graph_edge.in_node.longitude,
                              graph_edge.out_node.longitude)
        graph_edge_miny = min(graph_edge.in_node.latitude,
                              graph_edge.out_node.latitude)
        graph_edge_maxx = max(graph_edge.in_node.longitude,
                              graph_edge.out_node.longitude)
        graph_edge_maxy = max(graph_edge.in_node.latitude,
                              graph_edge.out_node.latitude)

        # insert graph edge into spatial index
        self.graph_edge_index.insert(graph_edge.id,
                                     (graph_edge_minx, graph_edge_miny,
                                      graph_edge_maxx, graph_edge_maxy))

    def _location_bearing(self, location):

        # if location has a previous neighbor and a next neighbor
        if ((location.prev_location is not None)
                and (location.next_location is not None)):

            # determine bearing using previous and next neighbors
            return self._path_bearing(location.prev_location,
                                      location.next_location)

        # if location has no previous neighbor, but has a next neighbor
        elif ((location.prev_location is None)
              and (location.next_location is not None)):

            # determine bearing using current location and next neighbor
            return self._path_bearing(location, location.next_location)

        # if location has a previous neighbor, but not a next neighbor
        elif ((location.prev_location is not None)
              and (location.next_location is None)):

            # determine bearing using previous neighbor and current location
            return self._path_bearing(location.prev_location, location)

        # if we reach here, there is an error
        return None

    def _find_closest_edges_in_graph(self, location, number_of_edges):
        return self.graph_edge_index.nearest(
            (location.longitude, location.latitude), number_of_edges)

    def _projection_onto_line(self, location1, location2, location3):
        return spatialfunclib.projection_onto_line(
            location1.latitude, location1.longitude, location2.latitude,
            location2.longitude, location3.latitude, location3.longitude)

    def _path_bearing(self, location1, location2):
        return spatialfunclib.path_bearing(location1.latitude,
                                           location1.longitude,
                                           location2.latitude,
                                           location2.longitude)

    def _distance(self, location1, location2):
        return spatialfunclib.distance(location1.latitude, location1.longitude,
                                       location2.latitude, location2.longitude)

    def _output_graph_to_db(self):

        # output that we are starting the database writing process...
        sys.stdout.write("\nOutputting graph to database... ")
        sys.stdout.flush()

        # connect to database
        conn = sqlite3.connect("cao_graph.db")

        # grab cursor
        cur = conn.cursor()

        # create nodes table
        cur.execute(
            "CREATE TABLE nodes (id INTEGER, latitude FLOAT, longitude FLOAT)")

        # create edges table
        cur.execute(
            "CREATE TABLE edges (id INTEGER, in_node INTEGER, out_node INTEGER)"
        )

        # remove values from nodes table
        #cur.execute("DELETE FROM nodes")

        # remove values from edges table
        #cur.execute("DELETE FROM edges")

        # commit creates
        conn.commit()

        # iterate through all graph nodes
        for graph_node in self.graph_nodes.values():

            # insert graph node into nodes table
            cur.execute("INSERT INTO nodes VALUES (" + str(graph_node.id) +
                        "," + str(graph_node.latitude) + "," +
                        str(graph_node.longitude) + ")")

        # iterate through all graph edges
        for graph_edge in self.graph_edges.values():

            # if the graph edge has volume greater than or equal to 3
            if (graph_edge.volume >= min_graph_edge_volume):

                # insert graph edge into edges table
                cur.execute("INSERT INTO edges VALUES (" + str(graph_edge.id) +
                            "," + str(graph_edge.in_node.id) + "," +
                            str(graph_edge.out_node.id) + ")")

        # commit inserts
        conn.commit()

        # close database connection
        conn.close()

        print "done."

    def _write_graph_edges_to_file(self):

        # output that we are starting the writing process
        sys.stdout.write("\nWriting graph edges to file... ")
        sys.stdout.flush()

        # open graph file
        graph_file = open('cao_edges.txt', 'w')

        # iterate through all graph_edges
        for graph_edge in self.graph_edges.values():

            # if the graph edge has volume greater than or equal to 3
            if (graph_edge.volume >= min_graph_edge_volume):

                # output edge to file
                graph_file.write(
                    str(graph_edge.in_node.latitude) + "," +
                    str(graph_edge.in_node.longitude) + "\n")
                graph_file.write(
                    str(graph_edge.out_node.latitude) + "," +
                    str(graph_edge.out_node.longitude) + "," +
                    str(graph_edge.volume) + "\n\n")

        # close graph file
        graph_file.close()

        print "done."

    def _reset_node_visited_flags(self):

        # iterate through all graph nodes
        for graph_node in self.graph_nodes.values():

            # set visited flag to False
            graph_node.visited = False
Example #44
0
def main():

    # You can edit these vars:
    # -----------------------
    filename = 'matrix_plot3.png'
    numberOfPoints = 200
    gridWidth = 10000
    gridHeight = 10000
    edgesMinimum = 2
    edgesMaximum = 4  # The maximum number of edges (connecting lines) a vertex can have
    # -----------------------
    edgesMaxDistance = (gridWidth / numberOfPoints) * 2

    # instantiate the Rtree class
    RtreeIndex = Rtree()

    # CREATE THE RANDOM POINTS:

    shapelyPointIndex = [
    ]  # Stores index = shapely object - We will reference this point from its Index from this point on.
    for idx in range(
            numberOfPoints):  # Each point gets its own index defined by i
        x = random.randint(0, gridWidth)
        y = random.randint(0, gridHeight)
        iPoint = Point(x, y)  # Create a new shapely POINT object
        shapelyPointIndex.append(iPoint)
        RtreeIndex.add(idx, (x, y, x, y))  # Add the point to the RTREE Index

    del idx  #unset temp variable
    # --------------------------------------------------------------------------

    #MultiPoint([(0, 0), (1, 1)])
    #point.coords
    #point.y   point.x

    lineMatrices = []
    ComplexLines = []
    graphIndex = {
    }  # This is a dictionary we will build into a graph/matrix - Each key will be an integer representing an index
    #                 and each value will be a dictionary of dictionaries representing edges.
    # iterate over all points to calculate each points nearest points
    # build line segments for each point to near points.
    # add all edges to a master complex line to compute intersection.
    for idx, point in enumerate(shapelyPointIndex):

        # Find nearby points quickly
        rtreeMatches = list()
        sRadiusX = gridWidth / 10
        sRadiusY = gridHeight / 10
        tries = 0
        while (len(rtreeMatches) < edgesMinimum +
               1):  # Add 1 because we can assume it will always find itself
            # Coords is a bounding-box to search within.
            coords = (point.x - sRadiusX, point.y - sRadiusY,
                      point.x + sRadiusX, point.y + sRadiusY)
            print "searching coords"
            print coords
            rtreeMatches = list(RtreeIndex.intersection(coords))
            print "found: ", rtreeMatches, "  ", len(rtreeMatches)
            tries += 1
            sRadiusX *= 1.5
            sRadiusY *= 1.5
            if (tries > 6):  #Don't run forever if there is a logic problem.
                break

        del tries, sRadiusX, sRadiusY

        # FIND POSSIBLE EDGES TO ADD BY SEARCHING REGION RECURSIVELY -----------
        # AND CALCULATE DISTANCES TO POSSIBLE POINTS ---------------------------
        # This dictionary will store our distances to each other point from this point.
        edgeDistances = {}
        # Calculate distances to matched points
        for pointIdx in rtreeMatches:
            if (pointIdx == idx):
                continue  # Don't record a distance to itself
            mPoint = shapelyPointIndex[pointIdx]
            edgeDistances[pointIdx] = round(
                mPoint.distance(point),
                2)  # keep the distance accuracy reasonable

        del mPoint, pointIdx, rtreeMatches

        # create a list that references the distances index for the closest indexes and is sorted by close to far.
        edgeDistancesIdx = sorted(edgeDistances, key=edgeDistances.get)
        #-----------------------------------------------------------------------

        # DECIDE WHICH EDGES TO ADD --------------------------------------------
        # Now add a minimum number of points, and try to keep them within a logic distance
        edgesAdded = 0
        edgesIdx = []  # this will contain indexes to our added edges
        for pointIdx in edgeDistancesIdx:
            distance = edgeDistances[pointIdx]
            # Stop adding edges if we've meant the minimum number of edges needed and the rest of the edges are too far away, or we have reach the maximum number of allowed edges
            if ((edgesAdded >= edgesMinimum and distance > edgesMaxDistance)
                    or edgesAdded >= edgesMaximum):
                break

            edgesIdx.append(pointIdx)

        del pointIdx

        #-----------------------------------------------------------------------
        # Initialize the graphIndex as a dict() for the current vertex if it hasn't been.
        if (idx not in graphIndex):
            graphIndex[idx] = {}
        #ADD THE EDGES TO THE GRID STRUCTURE -----------------------------------
        for pointIdx in edgesIdx:
            # Add the edge
            graphIndex[idx][pointIdx] = edgeDistances[pointIdx]
            # Add the reverse edge (so both points share an edge)
            if pointIdx not in graphIndex:
                graphIndex[pointIdx] = {}
            graphIndex[pointIdx][idx] = edgeDistances[pointIdx]

    #-----------------------------------------------------------------------

    # Print out the graph of vertices
    pprint.pprint(graphIndex)

    # Randomely select a Start Vertex, and an End Vertex for Shortest Path
    # calculation
    startIdx = random.randint(0, len(graphIndex) - 1)
    endIdx = startIdx
    # Calculate a random end index - and make sure its not the same as the start
    while (endIdx == startIdx):
        endIdx = random.randint(0, len(graphIndex) - 1)

    # Setup shortest path calculation!
    print "Calculating Shortest Path:\n"

    # (8894.6959143222557, [11, 5, 8L, 7, 9])
    # GraphIndex is a dictionary of dictionaries, startIdx is the INDEX of the startpoint, endIdx is the index of the endpoint vertex.
    shortestPath = dijkstra.shortestpath(graphIndex, startIdx, endIdx)
    shortestPathVertices = shortestPath[1]
    shortestPathDistance = shortestPath[0]

    print "Shortest Path Vertices:"
    print shortestPathVertices, "\n"

    del shortestPath

    #_-------------------------------------------------------------------------------
    # DRAW A PLOT FOR THE LINES CALCULATED ABOVE:
    import matplotlib
    matplotlib.use('Agg')  # Do NOT attempt to open X11 instance
    from pylab import *
    from matplotlib.patches import Circle
    import matplotlib.pyplot as pyplot
    from matplotlib.text import *

    mylist = lineMatrices

    matplotlib.rcParams['lines.linewidth'] = 2

    pyplot.axis([0, gridWidth, 0, gridHeight])
    pyplot.grid(True)
    # Setting the axis labels.
    pyplot.xlabel('X Space')
    pyplot.ylabel('Y Space')

    figure = pyplot.figure()
    labels = figure.add_subplot(111, projection='rectilinear')

    #Give the plot a title
    pyplot.title('Shapely Shortest Path Simulation')
    del idx
    if not isinstance(mylist, list):
        print "The matrix is not a list!"
        print type(mylist).__name__

    for idx, edges in graphIndex.iteritems():
        vertex = shapelyPointIndex[idx]

        for edgeIdx, edgeDistance in edges.iteritems():
            # This shouldn't happen, but lets just make sure.
            # DONT PLOT A PATH TO OURSELF
            if (edgeIdx == idx):
                continue
            # Get the edges point-coordinates
            edgePoint = shapelyPointIndex[edgeIdx]

            # Delete the reverse edge so we don't plot the line twice.
            if (edgeIdx in graphIndex):
                del graphIndex[edgeIdx][idx]

            # Print Debuggin Information
            print "PLOTTING EDGE: [%s] to [%s]    X:[%s] Y:[%s]  DIS:[%s] " % (
                idx, edgeIdx, edgePoint.x, edgePoint.y, edgeDistance)

            # Plot the edge!
            pyplot.plot([vertex.x, edgePoint.x], [vertex.y, edgePoint.y],
                        'b-',
                        alpha=0.3,
                        linewidth=.2,
                        markersize=1)

            # FIND THE MID-POINT OF THE LINE:
            xMidpoint = (vertex.x + edgePoint.x) / 2
            yMidpoint = (vertex.y + edgePoint.y) / 2

            #print "Plotting Text [%s] [%s]" % (xMidpoint, yMidpoint)
            # Figure out arrows later... arrowprops=dict(facecolor='black', linewidth=2,  alpha=0.4),

            # ANNOTATE THE LENGTH OF THE LINE AT ITS MIDPOINT
            labels.annotate(edgeDistance,
                            xy=(xMidpoint, yMidpoint),
                            xytext=(xMidpoint + 80, yMidpoint),
                            alpha=0.4,
                            size='4',
                            color='green')
            # end for ----------------------------------------------------------

        # Plot the VERTEX as a Red Circle
        pyplot.plot(vertex.x, vertex.y, 'ro', linewidth=2, markersize=2)
        # Annotate the VERTEX by its INDEX
        labels.annotate(idx,
                        xy=(vertex.x, vertex.y),
                        xytext=(vertex.x + 50, vertex.y),
                        alpha=0.6,
                        size='6',
                        color='red')

    print "Graphing Shortest Path..."
    print "START: %s  END: %s" % (startIdx, endIdx)

    #shortestPathVertices
    for idx, vertexIdx in enumerate(shortestPathVertices):

        if (vertexIdx == endIdx):
            break  # We are done

        xy1 = shapelyPointIndex[vertexIdx]  # this is the start of the line
        vertex2 = shortestPathVertices[
            idx +
            1]  # The end of the line is the next item in the list shortest path list of indexes
        xy2 = shapelyPointIndex[vertex2]  #this is the end of the line

        pyplot.plot([xy1.x, xy2.x], [xy1.y, xy2.y],
                    'r--',
                    alpha=0.7,
                    linewidth=2,
                    markersize=1)
        print "PLOT -> SHORTEST PATH: [%s] to [%s]" % (vertexIdx, vertex2)

    print "Saving Plot Image %s" % (filename)
    pyplot.savefig(os.getcwd() + '/' + str(filename), dpi=240)
    print "\n\n"
    """
Example #45
0
class Datasource:
    """ Store an exploded representation of a data source, so it can be simplified.
    """
    def __init__(self, srs, geom_type, fields, values, shapes):
        """ Use load() to call this constructor.
        """
        self.srs = srs
        self.fields = fields
        self.geom_type = geom_type
        self.values = values
        self.shapes = shapes

        # this will be changed later
        self.tolerance = 0

        # guid, src1_id, src2_id, line_id, x1, y1, x2, y2

        db = connect(':memory:').cursor()

        db.execute("""CREATE table segments (
                        
                        -- global identifier for this segment
                        guid    INTEGER PRIMARY KEY AUTOINCREMENT,
        
                        -- identifiers for source shape or shapes for shared borders
                        src1_id INTEGER,
                        src2_id INTEGER,
                        
                        -- global identifier for this line
                        line_id INTEGER,
                        
                        -- start and end coordinates for this segment
                        x1      REAL,
                        y1      REAL,
                        x2      REAL,
                        y2      REAL,
                        
                        -- flag
                        removed INTEGER
        
                      )""")

        db.execute('CREATE INDEX segments_lines ON segments (line_id, guid)')
        db.execute('CREATE INDEX shape1_parts ON segments (src1_id)')
        db.execute('CREATE INDEX shape2_parts ON segments (src2_id)')

        self.db = db
        self.rtree = Rtree()
        self.memo_line = make_memo_line()

    def _indexes(self):
        return range(len(self.values))

    def simplify(self, tolerance, verbose=False):
        """ Simplify the polygonal linework.
        
            This method can be called multiple times, but the process is
            destructive so it must be called with progressively increasing
            tolerance values.
        """
        if tolerance < self.tolerance:
            raise Exception(
                'Repeat calls to simplify must have increasing tolerances.')

        self.tolerance = tolerance

        q = 'SELECT line_id, COUNT(guid) AS guids FROM segments WHERE removed=0 GROUP BY line_id order by guids DESC'
        line_ids = [line_id for (line_id, count) in self.db.execute(q)]

        stable_lines = set()

        while True:

            was = self.db.execute(
                'SELECT COUNT(*) FROM segments WHERE removed=0').fetchone()[0]

            preserved, popped = set(), False

            for line_id in line_ids:

                if line_id in stable_lines:
                    continue

                # For each coordinate that forms the apex of a two-segment
                # triangle, find the area of that triangle and put it into a list
                # along with the segment identifier and the resulting line if the
                # triangle were flattened, ordered from smallest to largest.

                rows = self.db.execute(
                    """SELECT guid, x1, y1, x2, y2
                                          FROM segments
                                          WHERE line_id = ?
                                          AND removed = 0
                                          ORDER BY guid""", (line_id, ))

                segs = [(guid, (x1, y1), (x2, y2))
                        for (guid, x1, y1, x2, y2) in rows]
                triples = [(segs[i][0], segs[i + 1][0], segs[i][1], segs[i][2],
                            segs[i + 1][2]) for i in range(len(segs) - 1)]
                triangles = [(guid1, guid2, Polygon([c1, c2, c3, c1]), c1, c3)
                             for (guid1, guid2, c1, c2, c3) in triples]
                areas = sorted([(triangle.area, guid1, guid2, c1, c3)
                                for (guid1, guid2, triangle, c1,
                                     c3) in triangles])

                min_area = self.tolerance**2

                if not areas or areas[0][0] > min_area:
                    # there's nothing to be done
                    stable_lines.add(line_id)

                    if verbose:
                        stderr.write('-')
                    continue

                # Reduce any segments that makes a triangle whose area is below
                # the minimum threshold, starting with the smallest and working up.
                # Mark segments to be preserved until the next iteration.

                for (area, guid1, guid2, ca, cb) in areas:
                    if area > min_area:
                        # there won't be any more points to remove.
                        break

                    if guid1 in preserved or guid2 in preserved:
                        # the current segment is too close to a previously-preserved one.
                        continue

                    # Check the resulting flattened line against the rest
                    # any of the original shapefile, to determine if it would
                    # cross any existing line segment.

                    (x1, y1), (x2, y2) = ca, cb
                    new_line = self.memo_line(x1, y1, x2, y2)

                    old_guids = self.rtree.intersection(bbox(x1, y1, x2, y2))
                    old_rows = self.db.execute(
                        'SELECT x1, y1, x2, y2 FROM segments WHERE guid IN (%s) AND removed=0'
                        % ','.join(map(str, old_guids)))
                    old_lines = [
                        self.memo_line(x1, y1, x2, y2)
                        for (x1, y1, x2, y2) in old_rows
                    ]

                    if True in [
                            new_line.crosses(old_line)
                            for old_line in old_lines
                    ]:
                        if verbose:
                            stderr.write('x%d' % line_id)
                        continue

                    preserved.add(guid1)
                    preserved.add(guid2)

                    popped = True

                    x1, y1, x2, y2 = ca[0], ca[1], cb[0], cb[1]

                    self.db.execute(
                        'UPDATE segments SET removed=1 WHERE guid=%d' % guid2)
                    self.db.execute(
                        'UPDATE segments SET x1=?, y1=?, x2=?, y2=? WHERE guid=?',
                        (x1, y1, x2, y2, guid1))

                    self.rtree.add(guid1, bbox(x1, y1, x2, y2))

                if verbose:
                    stderr.write('.')

            if verbose:
                print >> stderr, ' reduced from', was, 'to',
                print >> stderr, self.db.execute(
                    'SELECT COUNT(guid) FROM segments WHERE removed=0'
                ).fetchone()[0],

            self.rtree = Rtree()

            for (guid, x1, y1, x2, y2) in self.db.execute(
                    'SELECT guid, x1, y1, x2, y2 FROM segments WHERE removed=0'
            ):
                self.rtree.add(guid1, bbox(x1, y1, x2, y2))

            if verbose:
                print >> stderr, '.'

            if not popped:
                break
Example #46
0
def populate_shared_segments_by_rtree(datasource, verbose=False):
    """
    """
    rtree = Rtree()
    indexes = datasource._indexes()

    for i in indexes:
        xmin, ymin, xmax, ymax = datasource.shapes[i].bounds

        xbuf = (xmax - xmin) * .001
        ybuf = (ymax - ymin) * .001

        bounds = (xmin - xbuf, ymin - ybuf, xmax + xbuf, ymax + ybuf)

        rtree.add(i, bounds)

    shared = [[] for i in indexes]

    for i in indexes:
        for j in rtree.intersection(datasource.shapes[i].bounds):

            if i >= j:
                continue

            shape1 = datasource.shapes[i]
            shape2 = datasource.shapes[j]

            if not shape1.intersects(shape2):
                continue

            if verbose:
                print >> stderr, 'Features %d and %d:' % (i, j), 'of', len(
                    indexes),

            border = linemerge(shape1.intersection(shape2))

            geoms = hasattr(border, 'geoms') and border.geoms or [border]

            for geom in geoms:
                try:
                    line_id = datasource.rtree.count(
                        datasource.rtree.get_bounds())
                except RTreeError:
                    line_id = 0

                coords = list(geom.coords)
                segments = [coords[k:k + 2] for k in range(len(coords) - 1)]

                for ((x1, y1), (x2, y2)) in segments:
                    datasource.db.execute(
                        """INSERT INTO segments
                                             (src1_id, src2_id, line_id, x1, y1, x2, y2, removed)
                                             VALUES (?, ?, ?, ?, ?, ?, ?, 0)""",
                        (i, j, line_id, x1, y1, x2, y2))

                    bbox = min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)
                    datasource.rtree.add(datasource.db.lastrowid, bbox)

                if verbose:
                    print >> stderr, len(coords), '-',

            shared[i].append(border)
            shared[j].append(border)

            if verbose:
                print >> stderr, border.type

    return shared
Example #47
0
    def simplify(self, tolerance, verbose=False):
        """ Simplify the polygonal linework.
        
            This method can be called multiple times, but the process is
            destructive so it must be called with progressively increasing
            tolerance values.
        """
        if tolerance < self.tolerance:
            raise Exception(
                'Repeat calls to simplify must have increasing tolerances.')

        self.tolerance = tolerance

        q = 'SELECT line_id, COUNT(guid) AS guids FROM segments WHERE removed=0 GROUP BY line_id order by guids DESC'
        line_ids = [line_id for (line_id, count) in self.db.execute(q)]

        stable_lines = set()

        while True:

            was = self.db.execute(
                'SELECT COUNT(*) FROM segments WHERE removed=0').fetchone()[0]

            preserved, popped = set(), False

            for line_id in line_ids:

                if line_id in stable_lines:
                    continue

                # For each coordinate that forms the apex of a two-segment
                # triangle, find the area of that triangle and put it into a list
                # along with the segment identifier and the resulting line if the
                # triangle were flattened, ordered from smallest to largest.

                rows = self.db.execute(
                    """SELECT guid, x1, y1, x2, y2
                                          FROM segments
                                          WHERE line_id = ?
                                          AND removed = 0
                                          ORDER BY guid""", (line_id, ))

                segs = [(guid, (x1, y1), (x2, y2))
                        for (guid, x1, y1, x2, y2) in rows]
                triples = [(segs[i][0], segs[i + 1][0], segs[i][1], segs[i][2],
                            segs[i + 1][2]) for i in range(len(segs) - 1)]
                triangles = [(guid1, guid2, Polygon([c1, c2, c3, c1]), c1, c3)
                             for (guid1, guid2, c1, c2, c3) in triples]
                areas = sorted([(triangle.area, guid1, guid2, c1, c3)
                                for (guid1, guid2, triangle, c1,
                                     c3) in triangles])

                min_area = self.tolerance**2

                if not areas or areas[0][0] > min_area:
                    # there's nothing to be done
                    stable_lines.add(line_id)

                    if verbose:
                        stderr.write('-')
                    continue

                # Reduce any segments that makes a triangle whose area is below
                # the minimum threshold, starting with the smallest and working up.
                # Mark segments to be preserved until the next iteration.

                for (area, guid1, guid2, ca, cb) in areas:
                    if area > min_area:
                        # there won't be any more points to remove.
                        break

                    if guid1 in preserved or guid2 in preserved:
                        # the current segment is too close to a previously-preserved one.
                        continue

                    # Check the resulting flattened line against the rest
                    # any of the original shapefile, to determine if it would
                    # cross any existing line segment.

                    (x1, y1), (x2, y2) = ca, cb
                    new_line = self.memo_line(x1, y1, x2, y2)

                    old_guids = self.rtree.intersection(bbox(x1, y1, x2, y2))
                    old_rows = self.db.execute(
                        'SELECT x1, y1, x2, y2 FROM segments WHERE guid IN (%s) AND removed=0'
                        % ','.join(map(str, old_guids)))
                    old_lines = [
                        self.memo_line(x1, y1, x2, y2)
                        for (x1, y1, x2, y2) in old_rows
                    ]

                    if True in [
                            new_line.crosses(old_line)
                            for old_line in old_lines
                    ]:
                        if verbose:
                            stderr.write('x%d' % line_id)
                        continue

                    preserved.add(guid1)
                    preserved.add(guid2)

                    popped = True

                    x1, y1, x2, y2 = ca[0], ca[1], cb[0], cb[1]

                    self.db.execute(
                        'UPDATE segments SET removed=1 WHERE guid=%d' % guid2)
                    self.db.execute(
                        'UPDATE segments SET x1=?, y1=?, x2=?, y2=? WHERE guid=?',
                        (x1, y1, x2, y2, guid1))

                    self.rtree.add(guid1, bbox(x1, y1, x2, y2))

                if verbose:
                    stderr.write('.')

            if verbose:
                print >> stderr, ' reduced from', was, 'to',
                print >> stderr, self.db.execute(
                    'SELECT COUNT(guid) FROM segments WHERE removed=0'
                ).fetchone()[0],

            self.rtree = Rtree()

            for (guid, x1, y1, x2, y2) in self.db.execute(
                    'SELECT guid, x1, y1, x2, y2 FROM segments WHERE removed=0'
            ):
                self.rtree.add(guid1, bbox(x1, y1, x2, y2))

            if verbose:
                print >> stderr, '.'

            if not popped:
                break
Example #48
0
from shapely.geometry import Point, Polygon
from shapely import wkt
from rtree import Rtree

import sys
import struct

output = sys.argv[1]

data_filename = output + '.data'
index_filename = output + '.data.idx'

data = open(data_filename, 'wb')
index = open(index_filename, 'wb')

tree = Rtree(output, overwrite=1)

id = 0
offset = 0

for l in sys.stdin:
    x = wkt.loads(l)
    tree.add(id, x.bounds)
    s = len(x.wkb)
    data.write(x.wkb)
    index.write(struct.pack('L', offset))
    offset += s
    id += 1
data.close()
index.close()
Example #49
0
        places[place_id] = keep

    print >> sys.stderr, "%d points discarded." % discarded

if not os.path.exists(point_file + '.cache'):
    print >> sys.stderr, "Caching points..."
    pickle.dump((names, places), file(point_file + ".cache", "w"), -1)

print >> sys.stderr, "Indexing..."
points = []
place_list = set()
for place_id, pts in places.items():
    for pt in pts:
        place_list.add((len(points), pt + pt, None))
        points.append((place_id, Point(pt)))
index = Rtree(place_list)
"""

REASSIGNMENT_PASSES = 10
iterations = 0
count = 0
queue = places.keys() + [None]
while len(queue) > 1:
    place_id = queue.pop(0)
    if place_id is None:
        count = 0
        iterations += 1
        queue.append(None)
        place_id = queue.pop(0)
    if not places[place_id]:
        del places[place_id]
    r = myAPIHelper.get_diagram(firstDiagID)

    try:
        assert r.status_code == 200
    except AssertionError as ae:
        print("Invalid reponse %s" % ae)
    else:
        op = json.loads(r.text)
        diaggeoms = op['geojson']
        sysid = op['sysid']
        desc = op['description']
        projectorpolicy = op['type']
        geoms, bounds = myDiagramDecomposer.processGeoms(diaggeoms)
        grid, allbounds = myGridGenerator.generateGrid(bounds)

    gridRTree = Rtree()
    for boundsid, bounds in allbounds.iteritems():
        gridRTree.insert(boundsid, bounds)

    choppedgeomsandareas = []
    choppedgeoms = []
    totalarea = 0
    for curgeom in geoms:
        curbounds = curgeom.bounds
        igridids = list(gridRTree.intersection(curbounds))

        for curintersectid in igridids:
            gridfeat = grid[curintersectid]
            ifeat = curgeom.intersection(gridfeat)
            ifeatarea = ifeat.area
            totalarea += ifeatarea
Example #51
0
# http://pypi.python.org/pypi/Rtree

# TODO: path hackery.
if __name__ == "__main__":
    import sys, os
    mypath = os.path.dirname(sys.argv[0])
    sys.path.append(os.path.abspath(os.path.join(mypath, "../../")))

from pyrtree.bench.bench_rtree import ITER, INTERVAL
from tests import RectangleGen
import time
from rtree import Rtree

if __name__ == "__main__":
    G = RectangleGen()
    idx = Rtree()  # this is a libspatialindex one.
    start = time.clock()
    interval_start = time.clock()
    for v in range(ITER):
        if 0 == (v % INTERVAL):
            # interval time taken, total time taken, # rects, cur max depth
            t = time.clock()

            dt = t - interval_start
            print("%d,%s,%f" % (v, "itime_t", dt))
            print("%d,%s,%f" % (v, "avg_insert_t", (dt / float(INTERVAL))))
            #print("%d,%s,%d" % (v, "max_depth", rt.node.max_depth()))
            #print("%d,%s,%d" % (v, "mean_depth", rt.node.mean_depth()))

            interval_start = time.clock()
        rect = G.rect(0.000001)
Example #52
0
 def add(self, id_, coords):
     with threading.RLock():
         Rtree.add(self, id_, coords)
Example #53
0
def snap_points_to_links(points, links):
    """Place points onto closest link in a set of links (arc/edges).
    
    Parameters
    ----------
    
    points : dict
        Point ID as key and (x,y) coordinate as value.
    
    links : list
        Elements are of type ``libpysal.cg.shapes.Chain``
        ** Note ** each element is a link represented as a chain with
        *one head and one tail vertex* in other words one link only.
    
    Returns
    -------
    
    point2link : dict
        Key [point ID (see points in arguments)]; value [a 2-tuple 
        ((head, tail), point) where (head, tail) is the target link,
        and point is the snapped location on the link.
    
    Examples
    --------
    
    >>> import spaghetti
    >>> from libpysal.cg.shapes import Point, Chain
    >>> points = {0: Point((1,1))}
    >>> link = [Chain([Point((0,0)), Point((2,0))])]
    >>> spaghetti.util.snap_points_to_links(points, link)
    {0: ([(0.0, 0.0), (2.0, 0.0)], array([1., 0.]))}
    
    """

    # instantiate an rtree
    rtree = Rtree()
    # set the smallest possible float epsilon on machine
    SMALL = numpy.finfo(float).eps

    # initialize network vertex to link lookup
    vertex_2_link = {}

    # iterate over network links
    for i, link in enumerate(links):

        # extract network link (x,y) vertex coordinates
        head, tail = link.vertices
        x0, y0 = head
        x1, y1 = tail

        if (x0, y0) not in vertex_2_link:
            vertex_2_link[(x0, y0)] = []

        if (x1, y1) not in vertex_2_link:
            vertex_2_link[(x1, y1)] = []

        vertex_2_link[(x0, y0)].append(link)
        vertex_2_link[(x1, y1)].append(link)

        # minimally increase the bounding box exterior
        bx0, by0, bx1, by1 = link.bounding_box
        bx0 -= SMALL
        by0 -= SMALL
        bx1 += SMALL
        by1 += SMALL

        # insert the network link and its associated
        # rectangle into the rtree
        rtree.insert(i, (bx0, by0, bx1, by1), obj=link)

    # build a KDtree on link vertices
    kdtree = cg.KDTree(list(vertex_2_link.keys()))

    point2link = {}

    for pt_idx, point in points.items():

        # first, find nearest neighbor link vertices for the point
        dmin, vertex = kdtree.query(point, k=1)
        vertex = tuple(kdtree.data[vertex])
        closest = vertex_2_link[vertex][0].vertices

        # Use this link as the candidate closest link:  closest
        # Use the distance as the distance to beat:     dmin
        point2link[pt_idx] = (closest, numpy.array(vertex))
        x0 = point[0] - dmin
        y0 = point[1] - dmin
        x1 = point[0] + dmin
        y1 = point[1] + dmin

        # Find all links with bounding boxes that intersect
        # a query rectangle centered on the point with sides
        # of length dmin * dmin
        rtree_lookup = rtree.intersection([x0, y0, x1, y1], objects=True)
        candidates = [cand.object for cand in rtree_lookup]
        dmin += SMALL
        dmin2 = dmin * dmin

        # of the candidate arcs, find the nearest to the query point
        for candidate in candidates:
            dist2cand, nearp = squared_distance_point_link(point, candidate.vertices)
            if dist2cand <= dmin2:
                closest = candidate.vertices
                dmin2 = dist2cand
                point2link[pt_idx] = (closest, nearp)

    return point2link
    allEvalSortedFeatures = []
    # iterate over the evaluations
    # iterate over the evaluations
    opfiles = []

    for cureval in evalspriority:
        print(
            colored(
                "Loading Evaluation data for %s system.." % cureval["name"],
                "yellow"))

        # a dictionary to hold features, we will ignore the red and red2 since allocation should not happen here.
        evalfeatcollection = {'green3': [], 'green2': [], 'green': []}
        # A dictionary to store the index of the features.
        evalfeatRtree = {
            'green3': Rtree(),
            'green2': Rtree(),
            'green': Rtree()
        }
        # open evaluation file
        filename = os.path.join(curPath, cureval['evalfilename'])
        try:
            assert os.path.isfile(filename)
        except AssertionError as e:
            print(colored("Input file %s does not exist" % filename, "red"))
            sys.exit(0)
        with open(filename) as data_file:
            try:
                geoms = json.load(data_file)
            except Exception as e:
                print(
    def detect_rn_component(self, status_matrix):
        node_pixels = np.where(status_matrix == GraphExtractor.NODE)
        nb_node_pixels = len(node_pixels[0])
        print('\n# of node pixels:{}'.format(nb_node_pixels))
        neighbor_deltas = [
            dxdy for dxdy in itertools.product([-1, 0, 1], [-1, 0, 1])
            if dxdy[0] != 0 or dxdy[1] != 0
        ]
        # node pixel -> center node
        nodes = {}
        node_pixel_spatial_index = Rtree()
        # [node pixel sequence (start and end must be node pixel)]
        connected_segments = []
        cnt = 1
        center_nodes = []
        node_pixel_id = 0
        for i, j in zip(node_pixels[0], node_pixels[1]):
            if (cnt % 100 == 0) or (cnt == nb_node_pixels):
                sys.stdout.write("\r" + str(cnt) + "/" + str(nb_node_pixels) +
                                 "... ")
                sys.stdout.flush()
            cnt += 1
            if status_matrix[i][j] == GraphExtractor.VISITED_NODE:
                continue
            # region merge neighbor node pixels
            status_matrix[i][j] = GraphExtractor.VISITED_NODE
            candidates = [(i, j)]
            node_pixels = []
            while len(candidates) > 0:
                node_pixel = candidates.pop()
                node_pixels.append(node_pixel)
                m, n = node_pixel
                for dm, dn in neighbor_deltas:
                    if status_matrix[m + dm][n + dn] == GraphExtractor.NODE:
                        status_matrix[m + dm][n +
                                              dn] = GraphExtractor.VISITED_NODE
                        candidates.append((m + dm, n + dn))
            center_node = CenterNodePixel(node_pixels)
            center_nodes.append(center_node)
            for node_pixel in node_pixels:
                nodes[node_pixel] = center_node
                node_pixel_spatial_index.insert(node_pixel_id,
                                                node_pixel,
                                                obj=node_pixel)
                node_pixel_id += 1
            # endregion

            # region find neighbor segments
            # mask current nodes, make sure the edge doesn't return to itself
            for m, n in node_pixels:
                status_matrix[m][n] = GraphExtractor.INVALID
            # find new road segment of the current node in each possible direction
            for node_pixel in node_pixels:
                connected_segment = self.detect_connected_segment(
                    status_matrix, node_pixel)
                if connected_segment is not None:
                    connected_segments.append(connected_segment)
            # restore masked nodes
            for m, n in node_pixels:
                status_matrix[m][n] = GraphExtractor.VISITED_NODE
            # endregion
        print('\n# of directly connected segments:{}'.format(
            len(connected_segments)))

        # there might be few edge pixels left, that should be fine
        nb_unprocessed_edge_pixels = np.sum(
            status_matrix[status_matrix == GraphExtractor.EDGE])
        print('unprocessed edge pixels:{}'.format(nb_unprocessed_edge_pixels))

        print('# of nodes:{}'.format(len(center_nodes)))
        print('# of segments:{}'.format(len(connected_segments)))
        return nodes, connected_segments
'''
@author Ben
In this example we will compare Shapely AGAINST RTREE for performance
NOTE: to get this to work I had to install libspatialindex 1.5 from source
and then:
export LD_LIBRARY_PATH=/usr/local/lib
'''

import random, os, sys, time, numpy

import rtree
from rtree import Rtree

# instantiate the Rtree class
p = rtree.index.Property(variant=rtree.index.RT_Star)
RtreeIndex = Rtree(properties=p)

import random, os, sys, time, numpy
from shapely import *
from shapely.geometry import Point

filename = 'rtree_radius_search.png'
numberOfPoints = 500
gridWidth = 10000
gridHeight = 10000
shapePoints = []

circleRadius = random.randint(500, 1500)
circleX = random.randint(0, gridWidth)
circleY = random.randint(0, gridHeight)
Example #57
0
class OSMDB:
    def __init__(self, dbname, overwrite=False, rtree_index=True):
        self.dbname = dbname

        if overwrite:
            try:
                os.remove(dbname)
            except OSError:
                pass

        self.conn = sqlite3.connect(dbname)

        if rtree_index:
            self.index = Rtree(dbname)
        else:
            self.index = None

        if overwrite:
            self.setup()

    def get_cursor(self):
        # Attempts to get a cursor using the current connection to the db. If we've found ourselves in a different thread
        # than that which the connection was made in, re-make the connection.

        try:
            ret = self.conn.cursor()
        except sqlite3.ProgrammingError:
            self.conn = sqlite3.connect(self.dbname)
            ret = self.conn.cursor()

        return ret

    def setup(self):
        c = self.get_cursor()
        c.execute(
            "CREATE TABLE nodes (id TEXT UNIQUE, tags TEXT, lat FLOAT, lon FLOAT, endnode_refs INTEGER DEFAULT 1)"
        )
        c.execute("CREATE TABLE ways (id TEXT UNIQUE, tags TEXT, nds TEXT)")
        self.conn.commit()
        c.close()

    def create_indexes(self):
        c = self.get_cursor()
        c.execute("CREATE INDEX nodes_id ON nodes (id)")
        c.execute("CREATE INDEX nodes_lon ON nodes (lon)")
        c.execute("CREATE INDEX nodes_lat ON nodes (lat)")
        c.execute("CREATE INDEX ways_id ON ways (id)")
        self.conn.commit()
        c.close()

    def populate(self,
                 osm_filename,
                 dryrun=False,
                 accept=lambda tags: True,
                 reporter=None,
                 create_indexes=True):
        print "importing %s osm from XML to sqlite database" % osm_filename

        c = self.get_cursor()

        self.n_nodes = 0
        self.n_ways = 0

        superself = self

        class OSMHandler(xml.sax.ContentHandler):
            @classmethod
            def setDocumentLocator(self, loc):
                pass

            @classmethod
            def startDocument(self):
                pass

            @classmethod
            def endDocument(self):
                pass

            @classmethod
            def startElement(self, name, attrs):
                if name == 'node':
                    self.currElem = Node(attrs['id'], float(attrs['lon']),
                                         float(attrs['lat']))
                elif name == 'way':
                    self.currElem = Way(attrs['id'])
                elif name == 'tag':
                    self.currElem.tags[attrs['k']] = attrs['v']
                elif name == 'nd':
                    self.currElem.nd_ids.append(attrs['ref'])

            @classmethod
            def endElement(self, name):
                if name == 'node':
                    if superself.n_nodes % 5000 == 0:
                        print "node %d" % superself.n_nodes
                    superself.n_nodes += 1
                    if not dryrun: superself.add_node(self.currElem, c)
                elif name == 'way':
                    if superself.n_ways % 5000 == 0:
                        print "way %d" % superself.n_ways
                    superself.n_ways += 1
                    if not dryrun and accept(self.currElem.tags):
                        superself.add_way(self.currElem, c)

            @classmethod
            def characters(self, chars):
                pass

        xml.sax.parse(osm_filename, OSMHandler)

        self.conn.commit()
        c.close()

        if not dryrun and create_indexes:
            print "indexing primary tables...",
            self.create_indexes()

        print "done"

    def set_endnode_ref_counts(self):
        """Populate ways.endnode_refs. Necessary for splitting ways into single-edge sub-ways"""

        print "counting end-node references to find way split-points"

        c = self.get_cursor()

        endnode_ref_counts = {}

        c.execute("SELECT nds from ways")

        print "...counting"
        for i, (nds_str, ) in enumerate(c):
            if i % 5000 == 0:
                print i

            nds = json.loads(nds_str)
            for nd in nds:
                endnode_ref_counts[nd] = endnode_ref_counts.get(nd, 0) + 1

        print "...updating nodes table"
        for i, (node_id, ref_count) in enumerate(endnode_ref_counts.items()):
            if i % 5000 == 0:
                print i

            if ref_count > 1:
                c.execute("UPDATE nodes SET endnode_refs = ? WHERE id=?",
                          (ref_count, node_id))

        self.conn.commit()
        c.close()

    def index_endnodes(self):
        print "indexing endpoint nodes into rtree"

        c = self.get_cursor()

        #TODO index endnodes if they're at the end of oneways - which only have one way ref, but are still endnodes
        c.execute("SELECT id, lat, lon FROM nodes WHERE endnode_refs > 1")

        for id, lat, lon in c:
            self.index.add(int(id), (lon, lat, lon, lat))

        c.close()

    def create_and_populate_edges_table(self, tolerant=False):
        self.set_endnode_ref_counts()
        self.index_endnodes()

        print "splitting ways and inserting into edge table"

        c = self.get_cursor()

        c.execute(
            "CREATE TABLE edges (id TEXT, parent_id TEXT, start_nd TEXT, end_nd TEXT, dist FLOAT, geom TEXT)"
        )

        for i, way in enumerate(self.ways()):
            try:
                if i % 5000 == 0:
                    print i

                subways = []
                curr_subway = [way.nds[0]
                               ]  # add first node to the current subway
                for nd in way.nds[1:-1]:  # for every internal node of the way
                    curr_subway.append(nd)
                    if self.node(
                            nd
                    )[4] > 1:  # node reference count is greater than one, node is shared by two ways
                        subways.append(curr_subway)
                        curr_subway = [nd]
                curr_subway.append(
                    way.nds[-1]
                )  # add the last node to the current subway, and store the subway
                subways.append(curr_subway)

                #insert into edge table
                for i, subway in enumerate(subways):
                    coords = [(lambda x: (x[3], x[2]))(self.node(nd))
                              for nd in subway]
                    packt = pack_coords(coords)
                    dist = sum([
                        vincenty(lat1, lng1, lat2, lng2)
                        for (lng1, lat1), (lng2, lat2) in cons(coords)
                    ])
                    c.execute("INSERT INTO edges VALUES (?, ?, ?, ?, ?, ?)",
                              ("%s-%s" % (way.id, i), way.id, subway[0],
                               subway[-1], dist, packt))
            except IndexError:
                if tolerant:
                    continue
                else:
                    raise

        print "indexing edges...",
        c.execute("CREATE INDEX edges_id ON edges (id)")
        c.execute("CREATE INDEX edges_parent_id ON edges (parent_id)")
        print "done"

        self.conn.commit()
        c.close()

    def edge(self, id):
        c = self.get_cursor()

        c.execute(
            "SELECT edges.*, ways.tags FROM edges, ways WHERE ways.id = edges.parent_id AND edges.id = ?",
            (id, ))

        try:
            ret = c.next()
            way_id, parent_id, from_nd, to_nd, dist, geom, tags = ret
            return (way_id, parent_id, from_nd, to_nd, dist,
                    unpack_coords(geom), json.loads(tags))
        except StopIteration:
            c.close()
            raise IndexError("Database does not have an edge with id '%s'" %
                             id)

        c.close()
        return ret

    def edges(self):
        c = self.get_cursor()

        c.execute(
            "SELECT edges.*, ways.tags FROM edges, ways WHERE ways.id = edges.parent_id"
        )

        for way_id, parent_id, from_nd, to_nd, dist, geom, tags in c:
            yield (way_id, parent_id, from_nd, to_nd, dist,
                   unpack_coords(geom), json.loads(tags))

        c.close()

    def add_way(self, way, curs=None):
        if curs is None:
            curs = self.get_cursor()
            close_cursor = True
        else:
            close_cursor = False

        curs.execute(
            "INSERT OR IGNORE INTO ways (id, tags, nds) VALUES (?, ?, ?)",
            (way.id, json.dumps(way.tags), json.dumps(way.nd_ids)))

        if close_cursor:
            self.conn.commit()
            curs.close()

    def add_node(self, node, curs=None):
        if curs is None:
            curs = self.get_cursor()
            close_cursor = True
        else:
            close_cursor = False

        curs.execute(
            "INSERT OR IGNORE INTO nodes (id, tags, lat, lon) VALUES (?, ?, ?, ?)",
            (node.id, json.dumps(node.tags), node.lat, node.lon))

        if close_cursor:
            self.conn.commit()
            curs.close()

    def nodes(self):
        c = self.get_cursor()

        c.execute("SELECT * FROM nodes")

        for node_row in c:
            yield node_row

        c.close()

    def node(self, id):
        c = self.get_cursor()

        c.execute("SELECT * FROM nodes WHERE id = ?", (id, ))

        try:
            ret = c.next()
        except StopIteration:
            c.close()
            raise IndexError("Database does not have node with id '%s'" % id)

        c.close()
        return ret

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

        if self.index:
            #print "YOUR'RE USING THE INDEX"
            id = list(self.index.nearest((lon, lat), 1))[0]
            #print "THE ID IS %d"%id
            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, ((nlat - lat)**2 + (nlon - lon)**2)**0.5)
                 for nid, nlat, nlon in c]

        if len(dists) == 0:
            return (None, None, None, None)

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

    def nearest_of(self, lat, lon, nodes):
        c = self.get_cursor()

        c.execute("SELECT id, lat, lon FROM nodes WHERE id IN (%s)" %
                  ",".join([str(x) for x in nodes]))

        dists = [(nid, nlat, nlon, ((nlat - lat)**2 + (nlon - lon)**2)**0.5)
                 for nid, nlat, nlon in c]

        if len(dists) == 0:
            return (None, None, None, None)

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

    def way(self, id):
        c = self.get_cursor()

        c.execute("SELECT id, tags, nds FROM ways WHERE id = ?", (id, ))

        try:
            id, tags_str, nds_str = c.next()
            ret = WayRecord(id, tags_str, nds_str)
        except StopIteration:
            raise Exception("OSMDB has no way with id '%s'" % id)
        finally:
            c.close()

        return ret

    def way_nds(self, id):
        c = self.get_cursor()
        c.execute("SELECT nds FROM ways WHERE id = ?", (id, ))

        (nds_str, ) = c.next()
        c.close()

        return json.loads(nds_str)

    def ways(self):
        c = self.get_cursor()

        c.execute("SELECT id, tags, nds FROM ways")

        for id, tags_str, nds_str in c:
            yield WayRecord(id, tags_str, nds_str)

        c.close()

    def count_ways(self):
        c = self.get_cursor()

        c.execute("SELECT count(*) FROM ways")
        ret = c.next()[0]

        c.close()

        return ret

    def count_edges(self):
        c = self.get_cursor()

        c.execute("SELECT count(*) FROM edges")
        ret = c.next()[0]

        c.close()

        return ret

    def delete_way(self, id):
        c = self.get_cursor()

        c.execute("DELETE FROM ways WHERE id = ?", (id, ))

        c.close()

    def bounds(self):
        c = self.get_cursor()
        c.execute("SELECT min(lon), min(lat), max(lon), max(lat) FROM nodes")

        ret = c.next()
        c.close()
        return ret

    def execute(self, sql, args=None):
        c = self.get_cursor()
        if args:
            for row in c.execute(sql, args):
                yield row
        else:
            for row in c.execute(sql):
                yield row
        c.close()

    def cursor(self):
        return self.get_cursor()
Example #58
0
def enclosure_tree(polygons):
    """
    Given a list of shapely polygons with only exteriors,
    find which curves represent the exterior shell or root curve
    and which represent holes which penetrate the exterior.

    This is done with an R-tree for rough overlap detection,
    and then exact polygon queries for a final result.

    Parameters
    -----------
    polygons : (n,) shapely.geometry.Polygon
       Polygons which only have exteriors and may overlap

    Returns
    -----------
    roots : (m,) int
        Index of polygons which are root
    contains : networkx.DiGraph
       Edges indicate a polygon is
       contained by another polygon
    """
    tree = Rtree()
    # nodes are indexes in polygons
    contains = nx.DiGraph()
    for i, polygon in enumerate(polygons):
        # if a polygon is None it means creation
        # failed due to weird geometry so ignore it
        if polygon is None or len(polygon.bounds) != 4:
            continue
        # insert polygon bounds into rtree
        tree.insert(i, polygon.bounds)
        # make sure every valid polygon has a node
        contains.add_node(i)

    # loop through every polygon
    for i in contains.nodes():
        polygon = polygons[i]
        # we first query for bounding box intersections from the R-tree
        for j in tree.intersection(polygon.bounds):
            # if we are checking a polygon against itself continue
            if (i == j):
                continue
            # do a more accurate polygon in polygon test
            # for the enclosure tree information
            if polygons[i].contains(polygons[j]):
                contains.add_edge(i, j)
            elif polygons[j].contains(polygons[i]):
                contains.add_edge(j, i)

    # a root or exterior curve has an even number of parents
    # wrap in dict call to avoid networkx view
    degree = dict(contains.in_degree())

    # convert keys and values to numpy arrays
    indexes = np.array(list(degree.keys()))
    degrees = np.array(list(degree.values()))

    # roots are curves with an even inward degree (parent count)
    roots = indexes[(degrees % 2) == 0]

    # if there are multiple nested polygons split the graph
    # so the contains logic returns the individual polygons
    if len(degrees) > 0 and degrees.max() > 1:
        # collect new edges for graph
        edges = []
        # find edges of subgraph for each root and children
        for root in roots:
            children = indexes[degrees == degree[root] + 1]
            edges.extend(contains.subgraph(np.append(children, root)).edges())
        # stack edges into new directed graph
        contains = nx.from_edgelist(edges, nx.DiGraph())
        # if roots have no children add them anyway
        contains.add_nodes_from(roots)

    return roots, contains
Example #59
0
class Graph:
    def __init__(self, all_trips):
        # trips
        self.all_trips = all_trips

        # cluster seeds
        self.cluster_seeds = {}
        self.cluster_seed_id = 0
        self.cluster_seed_index = Rtree()

        # graph edges
        self.graph_edges = {}  # indexed by "edge id"
        self.graph_edge_id = 0
        self.graph_edge_lookup = {}  # indexed by "location1_id,location2_id"

    def cluster_traces(self):
        self._create_all_trip_edges()
        self._generate_cluster_seeds()
        self._cluster_seeds_with_traces()
        self._generate_graph_edges()
        self._output_graph_to_db()

    def _generate_graph_edges(self):

        sys.stdout.write("Generating graph edges... ")
        sys.stdout.flush()

        # iterate through all trips
        for trip in self.all_trips:

            # grab trip edges
            trip_edges = trip.edges.values()

            # put trip edges in order
            trip_edges.sort(key=lambda x: x.id)

            # storage for previous cluster
            prev_cluster = None

            # iterate through trip edges
            for trip_edge in trip_edges:

                # if the current trip edge is clustered
                if (trip_edge.cluster is not None):

                    # create a graph edge between the previous cluster and the current cluster
                    self._create_graph_edge(prev_cluster, trip_edge.cluster)

                    # update previous cluster with current cluster
                    prev_cluster = trip_edge.cluster

        # output graph edges
        self._write_graph_edges_to_file()

        print "done."

    def _create_graph_edge(self, in_node, out_node):

        # if in_node or out_node is None
        if ((in_node is None) or (out_node is None)):

            # return without doing anything
            return

        # see if we can find an existing graph edge with the same nodes
        existing_graph_edge = self._find_graph_edge(in_node, out_node)

        # if there is no existing graph edge with the same nodes
        if (existing_graph_edge is None):

            # create new graph edge object
            new_graph_edge = Edge(self.graph_edge_id, in_node, out_node)

            # add new graph edge to graph edge dictionary
            self.graph_edges[new_graph_edge.id] = new_graph_edge

            # add new graph edge to graph edge lookup dictionary
            self.graph_edge_lookup[str(in_node.id) + "," +
                                   str(out_node.id)] = new_graph_edge

            # increment graph edge id
            self.graph_edge_id += 1

    def _find_graph_edge(self, node1, node2):

        # generate edge lookup key
        edge_lookup_key = str(node1.id) + "," + str(node2.id)

        # if edge is in lookup table
        if (edge_lookup_key in self.graph_edge_lookup.keys()):

            # return the matching edge
            return self.graph_edge_lookup[edge_lookup_key]

        # if the edge wasn't in the lookup table
        return None

    def _cluster_seeds_with_traces(self):

        # storage for total cluster distance moved
        total_cluster_distance_moved = float('infinity')

        # iterate until total cluster distance moved below threshold
        while (total_cluster_distance_moved >=
               cluster_distance_moved_threshold):

            # find all points on traces and move clusters
            total_cluster_distance_moved = self._find_points_on_traces()

            # write cluster seeds to file
            self._write_cluster_seeds_to_file(
                "edelkamp_cluster_seeds_clustered.txt")

    def _find_points_on_traces(self):

        # counter for cluster seeds
        seed_counter = 1

        # storage for total cluster distance moved
        total_cluster_distance_moved = 0.0

        # iterate through all cluster seeds
        for cluster_seed in self.cluster_seeds.values():

            # clear current trace points from cluster
            cluster_seed.clear_trace_points()

            sys.stdout.write("\rFinding intersecting points with cluster " +
                             str(seed_counter) + "/" +
                             str(len(self.cluster_seeds)) + "... ")
            sys.stdout.flush()

            # increment seed counter
            seed_counter += 1

            # determine leftward cluster bearing
            leftward_bearing = math.fmod((cluster_seed.bearing - 90.0) + 360.0,
                                         360.0)

            # determine rightward cluster bearing
            rightward_bearing = math.fmod(
                (cluster_seed.bearing + 90.0) + 360.0, 360.0)

            # storage for candidate trace points
            candidate_trace_points = []

            # iterate through all trips
            for trip in self.all_trips:

                # find leftward intersection points with trip
                candidate_trace_points.extend(
                    self._find_intersection_points(trip, cluster_seed,
                                                   leftward_bearing))

                # find rightward intersection points with trip
                candidate_trace_points.extend(
                    self._find_intersection_points(trip, cluster_seed,
                                                   rightward_bearing))

            # add candidate trace points to cluster
            cluster_seed.add_trace_points(candidate_trace_points)

            # recompute cluster centroid
            total_cluster_distance_moved += cluster_seed.recompute_cluster_centroid(
            )

            # clear current trace points from cluster
            cluster_seed.clear_trace_points()

            # add candidate trace points to cluster, again
            cluster_seed.add_trace_points(candidate_trace_points)

        # normalize total cluster distance moved by number of seeds
        total_cluster_distance_moved = (total_cluster_distance_moved /
                                        len(self.cluster_seeds.values()))

        # and we're done!
        print "done (clusters moved an average of " + str(
            total_cluster_distance_moved) + " meters)."

        # return total cluster distance moved
        return total_cluster_distance_moved

    def _find_intersection_points(self, trip, cluster, cluster_bearing):

        # find all nearby trip edge id's
        nearby_trip_edge_ids = self._find_nearby_trip_edge_ids(
            cluster, edge_bounding_box_size, trip.edge_index)

        # storage for intersection points
        intersection_points = []

        # iterate through all nearby edge id's
        for edge_id in nearby_trip_edge_ids:

            # grab current edge
            edge = trip.edges[edge_id]

            # determine intersection point between edge and cluster
            intersection_point = self._intersection_point(
                edge.in_node, edge.bearing, cluster, cluster_bearing)

            # if there is an intersection point
            if (intersection_point is not None):

                # determine distance from edge in_node to intersection point
                intersection_distance = self._distance_coords(
                    edge.in_node.latitude, edge.in_node.longitude,
                    intersection_point[0], intersection_point[1])

                # if intersection distance is less than edge length
                if (intersection_distance <= edge.length):

                    # this edge has a valid intersection point
                    intersection_points.append(
                        TracePoint(intersection_point[0],
                                   intersection_point[1], edge.bearing, edge))

        # return all intersection points for this trip
        return intersection_points

    def _generate_cluster_seeds(self):

        # iterate through all trips
        for i in range(0, len(self.all_trips)):

            sys.stdout.write("\rCluster seeding trip " + str(i + 1) + "/" +
                             str(len(self.all_trips)) + "... ")
            sys.stdout.flush()

            # grab current trip
            trip = self.all_trips[i]

            # set last cluster seed distance to zero for first trip location
            trip.locations[0].last_cluster_seed_distance = 0.0

            # iterate through all trip locations
            for j in range(1, len(trip.locations)):

                # drop cluster seeds along current edge every 50 meters
                self._drop_cluster_seeds_along_edge(trip.locations[j - 1],
                                                    trip.locations[j])

        print "done (generated " + str(len(
            self.cluster_seeds)) + " cluster seeds)."

        # write cluster seeds to file
        self._write_cluster_seeds_to_file("edelkamp_cluster_seeds_initial.txt")

    def _drop_cluster_seeds_along_edge(self, in_node, out_node):

        # determine edge length
        edge_length = self._distance(in_node, out_node)

        # determine distance along edge for first cluster seed
        first_cluster_seed_distance = (cluster_seed_interval -
                                       in_node.last_cluster_seed_distance)

        # storage for relative cluster seed intervals
        rel_cluster_seed_intervals = []

        # storage for current cluster seed distance along this edge
        curr_cluster_seed_distance = first_cluster_seed_distance

        # determine the relative cluster seed intervals needed for this edge
        while (curr_cluster_seed_distance <= edge_length):

            # append current cluster seed distance to relative cluster seed interval list
            rel_cluster_seed_intervals.append(curr_cluster_seed_distance)

            # increment current cluster seed distance
            curr_cluster_seed_distance += cluster_seed_interval

        # determine bearing of current edge
        edge_bearing = self._path_bearing(in_node, out_node)

        # create cluster seeds for edge
        for i in range(0, len(rel_cluster_seed_intervals)):

            # determine fraction along current edge to drop cluster seed
            fraction_along = (rel_cluster_seed_intervals[i] / edge_length)

            # determine point along line to drop cluster seed
            (new_cluster_seed_latitude,
             new_cluster_seed_longitude) = self._point_along_line(
                 in_node, out_node, fraction_along)

            # locate nearest existing cluster seeds
            closest_cluster_seeds = list(
                self.cluster_seed_index.nearest(
                    (new_cluster_seed_longitude, new_cluster_seed_latitude),
                    25))

            # if there does not exist a closest existing cluster seed
            if (len(closest_cluster_seeds) == 0):

                # create a new cluster seed
                new_cluster_seed = self._create_new_cluster_seed(
                    new_cluster_seed_latitude, new_cluster_seed_longitude,
                    edge_bearing)

            # else, if there exists a closest existing cluster seed
            elif (len(closest_cluster_seeds) > 0):

                # storage for matched cluster seed
                matched_cluster_seed = None

                # iterate through closest existing cluster seeds
                for curr_cluster_seed_id in closest_cluster_seeds:

                    # grab current cluster seed
                    curr_cluster_seed = self.cluster_seeds[
                        curr_cluster_seed_id]

                    # compute distance to current cluster seed
                    distance = self._distance_coords(
                        new_cluster_seed_latitude, new_cluster_seed_longitude,
                        curr_cluster_seed.latitude,
                        curr_cluster_seed.longitude)

                    # determine bearing difference between edge and current cluster seed
                    bearing_difference = math.cos(
                        math.radians(edge_bearing - curr_cluster_seed.bearing))

                    # if current cluster is less than 50 meters away and bearing difference is less than or equal to 45 degrees
                    if ((distance <= cluster_seed_interval)
                            and (bearing_difference >=
                                 cluster_bearing_difference_limit)):

                        # store current cluster seed as matched cluster seed
                        matched_cluster_seed = curr_cluster_seed

                        # stop searching
                        break

                # if there was not a matched cluster seed
                if (matched_cluster_seed is None):

                    # create a new cluster seed
                    new_cluster_seed = self._create_new_cluster_seed(
                        new_cluster_seed_latitude, new_cluster_seed_longitude,
                        edge_bearing)

            # update last cluster seed distance
            out_node.last_cluster_seed_distance = self._distance_coords(
                new_cluster_seed_latitude, new_cluster_seed_longitude,
                out_node.latitude, out_node.longitude)

        # if no cluster seeds were generated along this edge
        if (len(rel_cluster_seed_intervals) == 0):

            # update last cluster seed distance
            out_node.last_cluster_seed_distance = (
                in_node.last_cluster_seed_distance + edge_length)

    def _create_new_cluster_seed(self, latitude, longitude, bearing):

        # create a new cluster seed
        new_cluster_seed = ClusterSeed(self.cluster_seed_id, latitude,
                                       longitude, bearing)

        # add new cluster seed to the cluster seeds dictionary
        self.cluster_seeds[new_cluster_seed.id] = new_cluster_seed

        # insert new cluster seed into spatial index
        self.cluster_seed_index.insert(
            new_cluster_seed.id,
            (new_cluster_seed.longitude, new_cluster_seed.latitude))

        # increment cluster seed id
        self.cluster_seed_id += 1

        # return new cluster seed
        return new_cluster_seed

    def _create_all_trip_edges(self):

        sys.stdout.write("Creating and indexing edges for all trips... ")
        sys.stdout.flush()

        # iterate through all trips
        for trip in self.all_trips:

            # add edge storage to trip
            trip.edges = {}

            # add edge index to trip
            trip.edge_index = Rtree()

            # storage for edge id
            trip_edge_id = 0

            # iterate through all trip locations
            for i in range(1, len(trip.locations)):

                # create new edge
                new_edge = Edge(trip_edge_id, trip.locations[i - 1],
                                trip.locations[i])

                # insert edge into dictionary
                trip.edges[trip_edge_id] = new_edge

                # insert edge into index
                self._index_trip_edge(new_edge, trip.edge_index)

                # increment trip edge id
                trip_edge_id += 1

        # done
        print "done."

    def _index_trip_edge(self, edge, edge_index):

        # determine edge minx, miny, maxx, maxy values
        edge_minx = min(edge.in_node.longitude, edge.out_node.longitude)
        edge_miny = min(edge.in_node.latitude, edge.out_node.latitude)
        edge_maxx = max(edge.in_node.longitude, edge.out_node.longitude)
        edge_maxy = max(edge.in_node.latitude, edge.out_node.latitude)

        # insert edge into spatial index
        edge_index.insert(edge.id,
                          (edge_minx, edge_miny, edge_maxx, edge_maxy))

    def _find_nearby_trip_edge_ids(self, location, distance, edge_index):

        # define longitude/latitude offset
        lon_offset = ((distance / 2.0) /
                      spatialfunclib.METERS_PER_DEGREE_LONGITUDE)
        lat_offset = ((distance / 2.0) /
                      spatialfunclib.METERS_PER_DEGREE_LATITUDE)

        # create bounding box
        bounding_box = (location.longitude - lon_offset,
                        location.latitude - lat_offset,
                        location.longitude + lon_offset,
                        location.latitude + lat_offset)

        # return nearby edge id's inside bounding box
        return list(edge_index.intersection(bounding_box))

    def _intersection_point(self, location1, location1_bearing, location2,
                            location2_bearing):
        return spatialfunclib.intersection_point(
            location1.latitude, location1.longitude, location1_bearing,
            location2.latitude, location2.longitude, location2_bearing)

    def _point_along_line(self, location1, location2, fraction_along):
        return spatialfunclib.point_along_line(location1.latitude,
                                               location1.longitude,
                                               location2.latitude,
                                               location2.longitude,
                                               fraction_along)

    def _path_bearing(self, location1, location2):
        return spatialfunclib.path_bearing(location1.latitude,
                                           location1.longitude,
                                           location2.latitude,
                                           location2.longitude)

    def _distance(self, location1, location2):
        return spatialfunclib.distance(location1.latitude, location1.longitude,
                                       location2.latitude, location2.longitude)

    def _distance_coords(self, location1_latitude, location1_longitude,
                         location2_latitude, location2_longitude):
        return spatialfunclib.distance(location1_latitude, location1_longitude,
                                       location2_latitude, location2_longitude)

    def _write_cluster_seeds_to_file(self,
                                     filename="edelkamp_cluster_seeds.txt"):

        # open graph file
        graph_file = open(filename, 'w')

        # iterate through all cluster_seeds
        for cluster_seed in self.cluster_seeds.values():

            # output cluster seed to file
            graph_file.write(
                str(cluster_seed.latitude) + "," +
                str(cluster_seed.longitude) + "," + str(cluster_seed.bearing) +
                "\n")

        # close graph file
        graph_file.close()

    def _write_graph_edges_to_file(self):

        # open graph file
        graph_file = open('edelkamp_cluster_edges.txt', 'w')

        # iterate through all graph_edges
        for graph_edge in self.graph_edges.values():

            # output edge to file
            graph_file.write(
                str(graph_edge.in_node.latitude) + "," +
                str(graph_edge.in_node.longitude) + "\n")
            graph_file.write(
                str(graph_edge.out_node.latitude) + "," +
                str(graph_edge.out_node.longitude) + "\n\n")

        # close graph file
        graph_file.close()

    def _output_graph_to_db(self):

        # output that we are starting the database writing process...
        sys.stdout.write("\nOutputting graph to database... ")
        sys.stdout.flush()

        # connect to database
        conn = sqlite3.connect("edelkamp_graph.db")

        # grab cursor
        cur = conn.cursor()

        # create nodes table
        cur.execute(
            "CREATE TABLE nodes (id INTEGER, latitude FLOAT, longitude FLOAT)")

        # create edges table
        cur.execute(
            "CREATE TABLE edges (id INTEGER, in_node INTEGER, out_node INTEGER)"
        )

        # remove values from nodes table
        #cur.execute("DELETE FROM nodes")

        # remove values from edges table
        #cur.execute("DELETE FROM edges")

        # commit creates
        conn.commit()

        # iterate through all cluster seeds
        for cluster_seed in self.cluster_seeds.values():

            # insert cluster seed into nodes table
            cur.execute("INSERT INTO nodes VALUES (" + str(cluster_seed.id) +
                        "," + str(cluster_seed.latitude) + "," +
                        str(cluster_seed.longitude) + ")")

        # iterate through all graph edges
        for graph_edge in self.graph_edges.values():

            # insert graph edge into edges table
            cur.execute("INSERT INTO edges VALUES (" + str(graph_edge.id) +
                        "," + str(graph_edge.in_node.id) + "," +
                        str(graph_edge.out_node.id) + ")")

        # commit inserts
        conn.commit()

        # close database connection
        conn.close()

        print "done."
Example #60
-1
def getFilesForBox(request):
    l = float( request.GET['x1'] )
    b = float( request.GET['y1'] )
    r = float( request.GET['x2'] )
    t = float( request.GET['y2'] )
    ser = request.GET['ser']
    begin = int(request.GET['begin'])
    num = int(request.GET['num'])

    index = Rtree('/home/renci/geoanalytics/geoanalytics-lib/fl')
    ids = list(index.intersection((l,b,r,t), objects=True))[begin:begin+num]
    if len(ids)>0:
        files = [{
            'name' : f.name,
            'filepath' : f.filepath,
            'bbox4326' : f.bbox4326,
            'metadata' : f.metadata,
            'type' : "raster",
            'band_metadata' : f.band_metadata,
            'projection' : f.projection
        } for f in [RasterFile.objects(id=i.object[0]).first() for i in filter(lambda x:x.object[1]==ser and x.object[2] == 'r' , ids)]] + [{
            'name' : f.name,
            'filepath' : f.filepath,
            'bbox4326' : f.bbox4326,
            'type' : "features",
            'attributes' : f.attribute_names,
            'layers' : [{'attributes' : zip(l.attribute_names, l.attribute_types), 
                         'geometry_type' : l.geometry_type, 
                         'feature_count' : l.feature_count} for l in f.layers]
        } for f in [VectorFile.objects(id=i.object[0]).first() for i in filter(lambda x:x.object[1]==ser and x.object[2] == 'v' , ids)]] 
        return HttpResponse(json.dumps(files), mimetype='application/json')
    else:
        return HttpResponse("[]", mimetype='application/json')