Ejemplo n.º 1
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)
Ejemplo n.º 2
0
    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."
Ejemplo n.º 3
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
 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()
Ejemplo n.º 5
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/spatialib
        # 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():
            # takes id, bbox, and segment/edge
            rtree.insert(e[0], e[1], e[2])

        return rtree
Ejemplo n.º 6
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 dict(g.in_degree()).items() if deg == 0]
    return roots, g
Ejemplo n.º 7
0
def test_min_edges():

    # run mod_boruvka on graph with high mv max and long edge and make sure
    # that the result is an MST
    # of eachother (otherwise they should be connected)
    g = graph_high_mvmax_long_edge()

    subgraphs = UnionFind()
    rtree = Rtree()

    # build min span forest via mod_boruvka
    msf_g = mod_boruvka(g, subgraphs=subgraphs, rtree=rtree)

    # use networkx to build mst and compare
    coord_list = msf_g.coords.values()
    c = np.array(coord_list)
    all_dists = np.sqrt(((c[np.newaxis, :, :] - c[:, np.newaxis, :]) ** 2).
                    sum(2))

    complete_g = nx.Graph(all_dists)
    mst_g = nx.minimum_spanning_tree(complete_g)

    mst_edge_set = set([frozenset(e) for e in mst_g.edges()])
    msf_edge_set = set([frozenset(e) for e in msf_g.edges()])
    assert msf_edge_set == mst_edge_set
Ejemplo n.º 8
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:
            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, polygon in enumerate(polygons):
        # if polygon creation failed ignore it
        if polygon is None:
            continue
        # 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 no parents
    # wrap in dict call to avoid networkx view
    in_degree = dict(contains.in_degree())
    roots = [n for n, deg in in_degree.items() if deg == 0]

    return roots, contains
Ejemplo n.º 9
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"
Ejemplo n.º 10
0
def blast_to_tree(blast_file, qgff=None, sgff=None):
    """
    create a series of rtree's from a blast file
    the gff files are used to adjust the blast positions
    from local to global.
    if the blast position are chromosome based, the gff files
    should not be specified.
    """
    if qgff and isinstance(qgff, str):
        qgff = GFFDict(qgff)
    if sgff and isinstance(sgff, str):
        sgff = GFFDict(sgff)

    r = {}
    counts = {}

    for line in open(blast_file):
        b = BlastLine(line)

        if not b.query in r:
            r[b.query] = {}
            counts[b.query] = {}
        if not b.subject in r[b.query]:
            r[b.query][b.subject] = {'blasts': [], 'tree': Rtree()}
            counts[b.query][b.subject] = 0
        d = r[b.query][b.subject]
        d['blasts'].append(b)

        smin, smax = b.sstart, b.sstop
        if smin > smax: smax, smin = smin, smax

        qmin, qmax = b.qstart, b.qstop
        query = b.query
        subject = b.subject

        if sgff is not None:
            s = sgff[b.subject]
            smin += s.start
            smax += s.start
            subject = s.seqid
        if qgff is not None:
            q = qgff[b.query]
            qmin += q.start
            qmax += q.start
            query = q.seqid

        #r[b.query][b.subject]['tree'].add(counts[b.query][b.subject], (b.qstart, smin, b.qstop, smax))
        d['tree'].add(counts[query][subject], (qmin, smin, qmax, smax))
        counts[query][subject] += 1
    return r
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
def test_dead_bypass():

    # run mod_boruvka on graph with dead node and make sure
    # all connected components are NOT within their respective mvMax
    # of eachother (otherwise they should be connected)
    g = graph_with_dead_node()

    subgraphs = UnionFind()
    rtree = Rtree()

    # build min span forest via mod_boruvka
    msf_g = mod_boruvka(g, subgraphs=subgraphs, rtree=rtree)

    # calculate all min distances between components
    # distances between all nodes (euclidean for now)
    coord_list = msf_g.coords.values()
    c = np.array(coord_list)
    all_dists = np.sqrt(((c[np.newaxis, :, :] - c[:, np.newaxis, :]) ** 2)
                .sum(2))

    # now get the component distances (min dist between components)
    components = subgraphs.connected_components()
    component_dists = {}

    # set init dists to inf
    for pair in itertools.product(components, components):
        component_dists[pair] = np.inf

    # keep the min distance between components
    for node_pair_dist in np.ndenumerate(all_dists):
        comp1 = subgraphs[node_pair_dist[0][0]]
        comp2 = subgraphs[node_pair_dist[0][1]]
        dist = node_pair_dist[1]
        if dist < component_dists[(comp1, comp2)]:
            component_dists[(comp1, comp2)] = dist

    # now check whether components are within
    # their respective mvmax of eachother
    # (if so, we've got a problem)
    missed_connections = []
    for pair in itertools.product(components, components):

        if pair[0] != pair[1] and \
           subgraphs.budget[pair[0]] >= component_dists[pair] and \
           subgraphs.budget[pair[1]] >= component_dists[pair]:
            missed_connections.append(pair)

    assert len(missed_connections) == 0, "missed connections: " + \
                                        str(missed_connections)
Ejemplo n.º 13
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')
Ejemplo n.º 14
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()
Ejemplo n.º 15
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
Ejemplo n.º 16
0
    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()
Ejemplo n.º 17
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')
Ejemplo n.º 18
0
def 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

    Parameters
    -----------
    polygons: (n,) list of shapely.geometry.Polygon objects

    Returns
    -----------
    roots: (m,) int, index of polygons which are root
    contains:  networkx.DiGraph, edges indicate a polygon
               contained by another polygon
    """
    tree = Rtree()
    for i, polygon in enumerate(polygons):
        if polygon is not None:
            tree.insert(i, polygon.bounds)
    count = len(polygons)
    # nodes are indexes in polygons
    contains = nx.DiGraph()
    # make sure every polygon is included
    contains.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]):
                contains.add_edge(i, j)
            elif polygons[j].contains(polygons[i]):
                contains.add_edge(j, i)
    roots = [n for n, deg in dict(contains.in_degree()).items() if deg == 0]
    return roots, contains
Ejemplo n.º 19
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
Ejemplo n.º 20
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
Ejemplo n.º 21
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)
Ejemplo n.º 22
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)
Ejemplo n.º 23
0
def load_rn_shp(path, is_directed=True):
    edge_spatial_idx = Rtree()
    edge_idx = {}
    # node uses coordinate as key
    # edge uses coordinate tuple as key
    g = nx.read_shp(path, simplify=True, strict=False)
    if not is_directed:
        g = g.to_undirected()
    # node attrs: nid, pt, ...
    for n, data in g.nodes(data=True):
        data['pt'] = SPoint(n[1], n[0])
        if 'ShpName' in data:
            del data['ShpName']
    # edge attrs: eid, length, coords, ...
    for u, v, data in g.edges(data=True):
        geom_line = ogr.CreateGeometryFromWkb(data['Wkb'])
        coords = []
        for i in range(geom_line.GetPointCount()):
            geom_pt = geom_line.GetPoint(i)
            coords.append(SPoint(geom_pt[1], geom_pt[0]))
        data['coords'] = coords
        data['length'] = sum([
            distance(coords[i], coords[i + 1]) for i in range(len(coords) - 1)
        ])
        env = geom_line.GetEnvelope()
        edge_spatial_idx.insert(data['eid'], (env[0], env[2], env[1], env[3]))
        edge_idx[data['eid']] = (u, v)
        del data['ShpName']
        del data['Json']
        del data['Wkt']
        del data['Wkb']
    print('# of nodes:{}'.format(g.number_of_nodes()))
    print('# of edges:{}'.format(g.number_of_edges()))
    if not is_directed:
        return UndirRoadNetwork(g, edge_spatial_idx, edge_idx)
    else:
        return RoadNetwork(g, edge_spatial_idx, edge_idx)
Ejemplo n.º 24
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
Ejemplo n.º 25
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]
Ejemplo n.º 26
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')
Ejemplo n.º 27
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
    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
Ejemplo n.º 29
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
Ejemplo n.º 30
-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')