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 _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 _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()
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
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
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
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
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 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
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)
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)
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')
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 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
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 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')
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
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
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
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)
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 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)
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
''' 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]
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')
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
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
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')