def find_common_path(self, current_adc_trajectory, last_adc_trajectory): current_path_points = current_adc_trajectory.trajectory_point last_path_points = last_adc_trajectory.trajectory_point current_path = [] for point in current_path_points: current_path.append([point.path_point.x, point.path_point.y]) last_path = [] for point in last_path_points: last_path.append([point.path_point.x, point.path_point.y]) if len(current_path) == 0 or len(last_path) == 0: return [], [] current_ls = LineString(current_path) last_ls = LineString(last_path) current_start_point = Point(current_path[0]) dist = last_ls.project(current_start_point) cut_lines = self.cut(last_ls, dist) if len(cut_lines) == 1: return [], [] last_ls = cut_lines[1] dist = current_ls.project(Point(last_path[-1])) if dist <= current_ls.length: current_ls = self.cut(current_ls, dist)[0] else: dist = last_ls.project(Point(current_path[-1])) last_ls = self.cut(last_ls, dist)[0] return current_ls.coords, last_ls.coords
def _add_slope(self, bounds, altitude1, altitude2, point1, point2, bottom=False): altitude_diff = altitude2-altitude1 altitude_middle = (altitude1+altitude2)/2 altitude_halfdiff = altitude_diff/2 altitude_base = altitude1 line = LineString([point1, point2]) minx, miny, maxx, maxy = bounds points_2d = [(minx-100, miny-100), (maxx+100, miny-100), (maxx+100, maxy+100), (minx-100, maxy+100)] points_3d = [] for i, (x, y) in enumerate(points_2d): point = Point((x, y)) pos = line.project(point) while pos <= 0 or pos >= line.length-1: line = scale(line, xfact=2, yfact=2, zfact=2) altitude_diff *= 2 altitude_halfdiff *= 2 altitude_base = altitude_middle-altitude_halfdiff pos = line.project(point) z = ((pos/line.length)*altitude_diff)+altitude_base points_3d.append((x, y, z/1000)) extrude = abs(altitude1-altitude2)/1000+100 if bottom: extrude = -extrude self._add_python( 'last_slope = add_polygon_3d(name=%(name)r, coords=%(coords)r, extrude=%(extrude)f)' % { 'name': 'tmpslope', 'coords': tuple(points_3d), 'extrude': extrude, } )
def _add_crossroads(new_edges, current_edges): new_new_edges = set() new_current_edges = set() split_current_edge = [False] * len(current_edges) for new_edge in new_edges: found_crossroad = False for current_edge_index, current_edge in enumerate(current_edges): if State._different_starts_and_ends(new_edge, current_edge): new_line_segment = LineString([(new_edge[0].x, new_edge[0].y), (new_edge[1].x, new_edge[1].y)]) current_line_segment = LineString(([(current_edge[0].x, current_edge[0].y), (current_edge[1].x, current_edge[1].y)])) intersection = new_line_segment.intersection(current_line_segment) if type(intersection) is ShapelyPoint: new_crossroad = Point(intersection.x, intersection.y, Point.TYPE_CROSSROAD) new_current_edges.update(State._split_edge(current_edge, new_crossroad)) new_new_edges.update(State._split_edge(new_edge, new_crossroad)) split_current_edge[current_edge_index] = True found_crossroad = True break if not found_crossroad: new_new_edges.add(new_edge) for current_edge_index, current_edge in enumerate(current_edges): if not split_current_edge[current_edge_index]: new_current_edges.add(current_edge) if set(current_edges) == new_current_edges and set(new_edges) == new_new_edges: return list(current_edges) + list(new_edges) else: return State._add_crossroads(list(new_new_edges), list(new_current_edges))
def append_to_included_groups(locs, d): for group_key in d.keys(): ref_gene_poly = LineString([(0.0, float(group_key[0])),(0.0, float(group_key[1]))]) locs_poly = LineString([(0, locs[2]), (0, locs[3])]) if ref_gene_poly.intersects(locs_poly): d[group_key].append(tuple(locs)) return d
def cut_line(cut_point, line, eps_mult=1e2): dist = line.project(cut_point) point = line.interpolate(dist) eps = line.distance(point) * eps_mult coords = list(line.coords) if point.coords[0] in coords: i = coords.index(point.coords[0]) if i == 0: return LineString(), line if i == len(coords) - 1: return line, LineString() start_segment = LineString(coords[:i + 1]) end_segment = LineString(coords[i:]) return start_segment, end_segment for i, p in enumerate(coords[:-1]): line_segment = LineString([coords[i], coords[i + 1]]) line_segment_buffer = line_segment.buffer(eps, resolution=1) if line_segment_buffer.contains(point): start_segment = LineString(coords[:i + 1] + [point]) end_segment = LineString([point] + coords[i + 1:]) return start_segment, end_segment raise Exception('point not found in line, consider raising eps_mult')
def getShortestDisLinePoint(pointLon, pointLat, lineCoords, earthR): #get shortest distance between point and line line = LineString(lineCoords) point = Point(pointLon, pointLat) closestCoord = line.interpolate(line.project(point)) distance = haversine(pointLon, pointLat, closestCoord.x, closestCoord.y, earthR) return distance
def identify_first_point_in_polygon(points, ddd=0.5): """ Identify the cycle beginning for the last point :param points: array of objects of PointX :param ddd: distance to the fist point ddd>0. :return -1 if do not close, or i if close in point i. """ if len(points) < 3: return -1 # last point lp = Point(points[-1]) first_point = len(points) - 2 # Distance between last point and a line segment distance_point_line = 2 * ddd # Distance is not less than ddd or less than 3 points. while not (distance_point_line < ddd and polyline_length(points[first_point:]) > 2): # next segment first_point -= 1 if first_point == -1: break pt1 = points[first_point + 1] pt2 = points[first_point] # Distance to the first point to the line segment line_segment = LineString([pt1, pt2]) distance_point_line = line_segment.distance(lp) return first_point
def clipLine(lineGeometry, pt1, pt2): """Returns a line cliipped to the extent of two given points""" # Assumes pt1, pt2 lie on line if lineGeometry is None or lineGeometry.isEmpty() or pt1 is None or pt2 is None: return QgsGeometry() line = LineString(lineGeometry.geometry()) d1 = line.project(Point(pt1)) d2 = line.project(Point(pt2)) if d1 < d2: start = pt1 ds = d1 end = pt2 de = d2 else: start = pt2 ds = d2 end = pt1 de = d1 clip = [] clip.append(start) for coord in line.coords: pt = Point(coord) dp = line.project(pt) if dp > ds and dp < de: clip.append(QgsPointV2(pt.x, pt.y)) clip.append(end) return QgsGeometry.fromPolyline(clip)
def setUp(self): self.point = Point(1, 1) self.line1 = LineString(([0, 0], [2, 0])) self.line2 = LineString(([3, 0], [3, 6])) self.multiline = MultiLineString([ list(self.line1.coords), list(self.line2.coords) ])
def lines_fusion(line1, line2): """ Validate each line segment for intersection. Intersection is checked as http://en.wikipedia.org/wiki/Line_segment_intersection :param line1: main line :param line2: line to be fused :return same line1 if there is no intersections with line2. else fused lines. """ # TODO use bounding boxes to speed up # Cross validation for each line segment in polylines. for i in range(len(line1) - 1, 0, -1): p1 = line1[i] p2 = line1[i - 1] # line segment l1 = LineString([p1, p2]) for j in range(len(line2) - 1, 0, -1): p3 = line2[j] p4 = line2[j - 1] l2 = LineString([p3, p4]) # Check Line intersection intersection = l1.intersection(l2) # if intersected if not intersection.is_empty: # take the line 1 from first point until the intersection and line2 inter_p = (intersection.coords.xy[0][0], intersection.coords.xy[1][0]) new_line = line2[:j] + [inter_p] + line1[i:] return new_line # no fusion return line1
def fitline_plot(df): ## best fit straight line of points slope, intercept = hcf.fitline(df) ## define Shapely linestring using westmost and eastmost endpoints point1 = Point(df['x_working'].min(), slope * df['x_working'].min() + intercept) point2 = Point(df['x_working'].max(), slope * df['x_working'].max() + intercept) ls = LineString([point1, point2]) ## iterate through dfframe, project each TS point on Shapely line. Determine position on line and absolute x,y value for index, row in df.iterrows(): pointN = Point(row['x_working'], row['y_working']) projectN = ls.project(pointN) df.set_value(index, 'position_on_line', projectN) globalN = ls.interpolate(projectN) df.set_value(index, 'x_project', globalN.x) df.set_value(index, 'y_project', globalN.y) offsetN = globalN.distance(pointN) df.set_value(index, 'offset_from_line', offsetN) df = df.sort_values(by='position_on_line', ascending='true') print df ## plot points projected on best fit line plt.scatter(df['x_project'], df['y_project'], color='pink') ## init Figure 2 plt.figure(num=2, figsize=(13, 3), dpi=80) plt.grid(True) # plt.axes().set_aspect('equal', 'dflim') plt.axis([df['position_on_line'].min() - 20, df['position_on_line'].max() + 20, df['z_working'].min() - 4, df['z_working'].max() + 4]) plt.scatter(df['position_on_line'], df['z_working'], color='black') plt.plot(df['position_on_line'], df['z_working'], color='black')
def create_centerline(self): """ Calculates the centerline of a polygon. Densifies the border of a polygon which is then represented by a Numpy array of points necessary for creating the Voronoi diagram. Once the diagram is created, the ridges located within the polygon are joined and returned. Returns: a MultiLinestring located within the polygon. """ minx = int(min(self.inputGEOM.envelope.exterior.xy[0])) miny = int(min(self.inputGEOM.envelope.exterior.xy[1])) border = np.array(self.densify_border(self.inputGEOM, minx, miny)) #print(border, minx, miny, self.dist) vor = Voronoi(border) vertex = vor.vertices lst_lines = [] for j, ridge in enumerate(vor.ridge_vertices): if -1 not in ridge: line = LineString([ (vertex[ridge[0]][0] + minx, vertex[ridge[0]][1] + miny), (vertex[ridge[1]][0] + minx, vertex[ridge[1]][1] + miny)]) if line.within(self.inputGEOM) and len(line.coords[0]) > 1: lst_lines.append(line) return MultiLineString(lst_lines)
def pymol_select_memb_old(pdb: MyPDB) -> set(): """ print a pymol selection line for all residues that are in the membrane !!! this assumes that cntr is at 0 0 0 and norm at 15 0 0 !!! """ from shapely.geometry import LineString, Point # create Points from center & thickness cntr_pnt = Point(pdb.memb_res.cntr.x, pdb.memb_res.cntr.y, pdb.memb_res.cntr.z) thkn_m_pnt = Point(-pdb.memb_res.thkn.x, pdb.memb_res.thkn.y, pdb.memb_res.thkn.z) thkn_pnt = Point(pdb.memb_res.thkn.x, pdb.memb_res.thkn.y, pdb.memb_res.thkn.z) # define the line between center and thickness line = LineString([thkn_m_pnt, thkn_pnt]) thickness = cntr_pnt.distance(thkn_pnt) result = set() # iterate over all CAs in the pdb for cid in sorted(pdb.chains.keys()): for rid in sorted(pdb[cid].residues.keys()): atom = pdb[cid][rid]['CA'] # the atom as a Point p = Point(atom.xyz.x, atom.xyz.y, atom.xyz.z) # projection of the CA atom on the center-thickness line np = line.interpolate(line.project(p)) # if the distance on the center-thickness line is smaller than 15, than this is in the membrane if cntr_pnt.distance(np) < thickness-0.1: result.add(atom.res_seq_num) return result
def test_linestring_geojson(self): '''Create a line that goes from west to east (clip on)''' self.defineGeometry('LINESTRING') geom = LineString( [(-180, 32), (180, 32)] ) self.insertTestRow(geom.wkt) # we should have a line that clips at 0... # for western hemisphere.... tile_mimetype, tile_content = utils.request(self.config_file_content, "vector_test", "geojson", 0, 0, 0) self.assertEqual(tile_mimetype, "text/json") geojson_result = json.loads(tile_content) west_hemisphere_geometry = asShape(geojson_result['features'][0]['geometry']) expected_geometry = LineString([(-180, 32), (0, 32)]) self.assertTrue(expected_geometry.almost_equals(west_hemisphere_geometry)) # for eastern hemisphere.... tile_mimetype, tile_content = utils.request(self.config_file_content, "vector_test", "geojson", 0, 1, 0) self.assertEqual(tile_mimetype, "text/json") geojson_result = json.loads(tile_content) east_hemisphere_geometry = asShape(geojson_result['features'][0]['geometry']) expected_geometry = LineString([(0, 32), (180, 32)]) self.assertTrue(expected_geometry.almost_equals(east_hemisphere_geometry))
def appendNewWay(coords, intersects, osmXml): way = etree.Element('way', visible='true', id=str(newOsmId('way'))) firstNid = 0 for i, coord in enumerate(coords): if i == 0: continue # the first and last coordinate are the same node = appendNewNode(coord, osmXml) if i == 1: firstNid = node.get('id') way.append(etree.Element('nd', ref=node.get('id'))) # Check each way segment for intersecting nodes int_nodes = {} try: line = LineString([coord, coords[i+1]]) except IndexError: line = LineString([coord, coords[1]]) for idx, c in enumerate(intersects): if line.buffer(0.0000015).contains(Point(c[0], c[1])) and c not in coords: t_node = appendNewNode(c, osmXml) for n in way.iter('nd'): if n.get('ref') == t_node.get('id'): break else: int_nodes[t_node.get('id')] = Point(c).distance(Point(coord)) for n in sorted(int_nodes, key=lambda key: int_nodes[key]): # add intersecting nodes in order way.append(etree.Element('nd', ref=n)) way.append(etree.Element('nd', ref=firstNid)) # close way osmXml.append(way) return way
def getRel(tri1, tri2): rels = set() ## get triangle center center = triangle_center(*tri1) #print 'center:' , center for i in xrange(3): #print 'vertex: ', tri2[i] angle = __calAngle__(center, tri2[i]) rels.add(__getRel__(angle)) if len(rels) >= 2: scenter = Point(center) #point in shapely form edges = [[tri2[0], tri2[1]], [tri2[1], tri2[2]], [tri2[0],tri2[2]]] for edge in edges: line = LineString(edge) isectPnt = line.interpolate(line.project(scenter)) angle = __calAngle__(center, (isectPnt.x, isectPnt.y)) rels.add(__getRel__(angle)) x_direction = set() y_direction = set() for rel in rels: if rel == WEST or rel == EAST: x_direction.add(rel) else: y_direction.add(rel) return [x_direction, y_direction]
def clipLine(lineGeometry, pt1, pt2): if lineGeometry is None or lineGeometry.isGeosEmpty() or pt1 is None or pt2 is None: return QgsGeometry() line = LineString(lineGeometry.asPolyline()) d1 = line.project(Point(pt1)) d2 = line.project(Point(pt2)) if d1 < d2: start = pt1 ds = d1 end = pt2 de = d2 else: start = pt2 ds = d2 end = pt1 de = d1 clip = [] clip.append(start) for coord in line.coords: pt = Point(coord) dp = line.project(pt) if dp > ds and dp < de: clip.append(QgsPoint(pt.x, pt.y)) clip.append(end) return QgsGeometry.fromPolyline(clip)
def project(p1, p2, p3): """Project a Point, p3 onto a line between Points p1 and p2. Uses Shapely and GEOS functions, which set distance to zero for all negative distances. Parameters: p1 (Point) : point at zero distance on line between p1 and p2. p2 (Point) : endpoint of line. p3 (Point) : the point to project. Returns: result (dict) : the projected Point, disctance along line, offset from line, and fractional distance along line. """ line = LineString([(p1.x, p1.y),(p2.x, p2.y)]) u = line.project(p3, normalized=True) d = line.project(p3, normalized=False) pt_xy = line.interpolate(d) pt = Point([pt_xy.x, pt_xy.y, p3.z]) # calculate the offset distance of p3 from the line if (p1.y - p2.y) * (p3.x - p2.x) - (p1.x - p2.x) * (p3.y - p2.y) < 0: offset = -pt.distance(p3) # the point is offset left of the line else: offset = pt.distance(p3) # the point is offset right of the line result = {'pt':pt, 'd':d, 'o':offset, 'u':u} return result
def my_view(request): start_lat, start_long = [request.matchdict['lat1'], request.matchdict['long1']] end_lat, end_long = [request.matchdict['lat2'], request.matchdict['long2']] start_lat = float(start_lat) start_long = float(start_long) end_lat = float(end_lat) end_long = float(end_long) zip_codes = [] required_polygon = [] with fiona.open('myproject/tl_2014_us_zcta510.shp', 'r') as f: for line in f: zip_code = int(line['properties']['ZCTA5CE10']) if zip_code > 90000 and zip_code < 96163: # check for California if line['geometry']['type'] == 'Polygon': polygon = line['geometry']['coordinates'] s = Polygon(polygon[0]) linestr = LineString([(start_long, start_lat), (end_long, end_lat)]) if linestr.intersects(s): zip_codes.append(zip_code) required_polygon.append(polygon[0]) else: multi_polygon = line['geometry']['coordinates'] for polygon in multi_polygon: s = Polygon(polygon[0]) linestr = LineString([(start_long, start_lat), (end_long, end_lat)]) if linestr.intersects(s): zip_codes.append(zip_code) required_polygon.append(polygon[0]) return dict(zip_codes=zip_codes, required_polygon=required_polygon)
def get_matched_trip_smooth(data, matched_folder): xs, ys, mx0, mx1, my0, my1 = ([], [], [], [], [], []) for tid in data.tid.unique(): matched_trip = pd.read_csv(matched_folder+'/matched_trip'+str(tid)+'.csv', sep=' ', names=['y','x','t','y0','x0','y1','x1']) matched_trip = matched_trip[matched_trip.t % 5 == 1] matched_trip = matched_trip.replace('unknown', 0) matched_trip.fillna(0) #print tid, len(trip), len(matched_trip), len(matched_trip[matched_trip.x0 == 'unknown']) for idx, row in matched_trip.iterrows(): #print row if row.y0 == 0 or row.x0 == 0: xs.append(0) ys.append(0) mx0.append(0) my0.append(0) mx1.append(0) my1.append(0) ''' xs.append(xs[-1]) ys.append(ys[-1]) mx0.append(mx0[-1]) my0.append(my0[-1]) mx1.append(mx1[-1]) my1.append(my1[-1]) ''' continue line = LineString([(float(row.x0),float(row.y0)),(float(row.x1),float(row.y1))]) mx0.append(float(row.x0)) my0.append(float(row.y0)) mx1.append(float(row.x1)) my1.append(float(row.y1)) p = Point(row.x, row.y) #print row.x, row.y, #print list(line.interpolate(line.project(p)).coords) _x, _y = list(line.interpolate(line.project(p)).coords)[0] xs.append(_x) ys.append(_y) data['mLon'] = xs data['mLat'] = ys data['mx0'] = mx0 data['my0'] = my0 data['mx1'] = mx1 data['my1'] = my1 ''' # naive fillna xs = [] ys = [] for idx, row in data.iterrows(): if row.mLon == 0: xs.append(xs[-1]) ys.append(ys[-1]) else: xs.append(row.mLon) ys.append(row.mLat) data.mLon = xs data.mLat = ys ''' return data
def acc2latlng(caseno): """Calculate the latitude/longitude and update into mongodb :param caseno: case number of the accident """ # get the cnty_rte and mile post acc = acc_col.find_one({'caseno':caseno}) # check exists if 'lat' in acc.keys() and 'lng' in acc.keys(): return rte_nbr = acc['rte_nbr'] cnty_rte = acc['cnty_rte'] milepost = acc['milepost'] if cnty_rte.index(rte_nbr) != 2: raise Exception("Unknown format") # get the road information rid = rte_nbr + cnty_rte[0:2] r_info = cnty_rte2linestring(rid) max_mp = r_info['rlist'][-1]['endmp'] ls = LineString( r_info['plist'] ) deg_mp = milepost / max_mp * ls.length # mile to degree acc_pos = ls.interpolate( deg_mp ) lng = acc_pos.coords[0][0] lat = acc_pos.coords[0][1] #print ls #print acc_pos # TODO, update the lat lng information acc_col.update( {'caseno':caseno}, {'$set':{'lat':lat, 'lng':lng}} )
def find_valid_edges(vertexes, edges, env, polygons): valid_edges = [] for i, p1 in enumerate(vertexes): print i for p2 in [x for x in vertexes if not x == p1]: add = True line2 = LineString([p1, p2]) if env.crosses(line2): continue xx, yy = line2.xy # Midpoint will lie within a shape if the line is composed of two vertices of the polygon m = Point(sum(xx)/2., sum(yy)/2.) if [x for x in polygons if m.within(x)]: continue # skip this edge if it is within a polygon for edge in edges: line1 = LineString(edge) if add and not line1 == line2 and line1.crosses(line2): add = False break if add: valid_edges.append([p1, p2]) return valid_edges
def test_line_intersection(self): line1 = LineString([(0, 0, 0), (1, 1, 1)]) line2 = LineString([(0, 1, 1), (1, 0, 0)]) interxn = line1.intersection(line2) self.assertTrue(interxn.has_z) self.assertEqual(interxn._ndim, 3) self.assertTrue(0.0 <= interxn.z <= 1.0)
def offset(self, distance): self.points.append(self.points[0]) line = LineString(self.getSequence()) offset = line.parallel_offset(distance, 'right', join_style=1) # return list(offset.coords) self.setSequence(list(offset.coords)) return self
def divide_polygon_for_intersection(self, segments): """ Generates multiple polygons based on cutting the fracture faces by line segments. """ R = self.build_rotation_matrix() fracture_poly_list = [] # face_poly_list = [] for point in self.points: rot_point = np.linalg.solve(R, point - self.center) fracture_poly_list.append(rot_point[:2]) seg_rot = [] for seg in segments: p1 = seg[0] p2 = seg[1] vec = p2 - p1 p1 = p1 - 100.0 * vec p2 = p2 + 100.0 * vec p1_rot = np.linalg.solve(R, p1 - self.center) p2_rot = np.linalg.solve(R, p2 - self.center) line = LineString((p1_rot[:2], p2_rot[:2])) dilated = line.buffer(1.0e-10) seg_rot.append(dilated) fracture_poly = Polygon(fracture_poly_list) divided_polygons = fracture_poly.difference(seg_rot[0]) return (divided_polygons, fracture_poly)
def fix_polygon(poly): """ Fix the polygon if it is bad formed. :param poly: :return: """ # print poly if len(poly) <= 3: return poly pol = Polygon(poly) if pol.is_valid: return poly final_line = LineString([poly[0], poly[-1]]) for i in range(len(poly) - 2, 0, -1): l = LineString(poly[i:i + 2]) if l.intersects(final_line): poly1 = poly[:i] + [poly[-1]] return fix_polygon(poly1) return poly
def test_line_intersection(self): line1 = LineString([(0, 0, 0), (1, 1, 1)]) line2 = LineString([(0, 1, 1), (1, 0, 0)]) interxn = line1.intersection(line2) self.failUnless(interxn.has_z) self.failUnless(interxn._ndim == 3) self.failUnless(0.0 <= interxn.z <= 1.0)
def project_tracks_to_road(tracks, road_segments): """ Compute tracks that fall into each road segment. Args: - tracks - road_segments Return: - track_on_road: a dictionary, each key is the index of a road segment. Each value is a set of indices of the tracks fall onto this road. """ track_on_road = {} for seg_idx in np.arange(len(road_segments)): track_on_road[seg_idx] = set([]) simplified_tracks = [] for track in tracks: line = LineString([(pt[0], pt[1]) for pt in track.utm]) simplified_track = line.simplify(10.0) simplified_tracks.append(simplified_track) # Compute road segment linestrings road_segment_linestrings = [] for r_seg in road_segments: r_start = r_seg.center - r_seg.half_length*r_seg.direction r_end = r_seg.center + r_seg.half_length*r_seg.direction r_linestring = LineString([r_start, r_end]) road_segment_linestrings.append(r_linestring) for seg_idx in np.arange(len(road_segments)): print seg_idx for track_idx in np.arange(len(tracks)): if road_segment_linestrings[seg_idx].distance(simplified_tracks[track_idx]) > 1.2*road_segments[seg_idx].half_width: continue track = tracks[track_idx] if len(track.utm) <= 1: continue for utm_idx in np.arange(len(track.utm)): utm = track.utm[utm_idx] if utm_idx == 0: direction = np.array([track.utm[utm_idx+1][0], track.utm[utm_idx+1][1]]) - \ np.array([track.utm[utm_idx][0], track.utm[utm_idx][1]]) elif utm_idx == len(track.utm) - 1: direction = np.array([track.utm[utm_idx][0], track.utm[utm_idx][1]]) - \ np.array([track.utm[utm_idx-1][0], track.utm[utm_idx-1][1]]) else: direction = np.array([track.utm[utm_idx+1][0], track.utm[utm_idx+1][1]]) - \ np.array([track.utm[utm_idx-1][0], track.utm[utm_idx-1][1]]) direction /= np.linalg.norm(direction) if np.dot(direction, road_segments[seg_idx].direction) < np.cos(np.pi/4.0): continue pt = Point(utm[0], utm[1]) if pt.distance(road_segment_linestrings[seg_idx]) < 1.2*road_segments[seg_idx].half_width: track_on_road[seg_idx].add(track_idx) break return track_on_road
def _cont_to_polys(self, cont_lats, cont_lons): polys = [] start_idx = 0 splits = [] while True: try: split_idx = cont_lats[start_idx:].index(99.99) splits.append(start_idx + split_idx) start_idx += split_idx + 1 except ValueError: break splits = [ -1 ] + splits + [ len(cont_lats) + 1 ] poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] # Intersect with the US boundary shape file. for plat, plon in zip(poly_lats, poly_lons): cont = LineString(zip(plon, plat)) if plat[0] != plat[-1] or plon[0] != plon[-1]: # If the line is not a closed contour, then it intersects with the edge of the US. Extend # the ends a little bit to make sure it's outside the edge. dln = np.diff(plon) dlt = np.diff(plat) pre = [ (plon[0] - 0.5 * dln[0], plat[0] - 0.5 * dlt[0]) ] post = [ (plon[-1] + 0.5 * dln[-1], plat[-1] + 0.5 * dlt[-1]) ] cont.coords = pre + list(cont.coords) + post # polygonize() will split the country into two parts: one inside the outlook and one outside. # Construct test_ln that is to the right of (inside) the contour and keep only the polygon # that contains the line test_ln = cont.parallel_offset(0.05, 'right') for poly in polygonize(self._conus.boundary.union(cont)): if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)): polys.append(poly) # Sort the polygons by area so we intersect the big ones with the big ones first. polys.sort(key=lambda p: p.area, reverse=True) # If any polygons intersect, replace them with their intersection. intsct_polys = [] while len(polys) > 0: intsct_poly = polys.pop(0) pops = [] for idx, poly in enumerate(polys): if intsct_poly.intersects(poly): intsct_poly = intsct_poly.intersection(poly) pops.append(idx) for pop_idx in pops[::-1]: polys.pop(pop_idx) intsct_polys.append(intsct_poly) return intsct_polys
def drifters(drifter_id, projection, resolution, extent): buoy_id = [] lat = [] lon = [] status = [] if drifter_id in ['all', 'active', 'inactive', 'not responding']: c = Crawl(app.config['DRIFTER_CATALOG_URL'], select=[".*.nc$"]) drifters = [d.name[:-3] for d in c.datasets] else: drifters = drifter_id.split(",") for d in drifters: with Dataset(app.config["DRIFTER_URL"] % d, 'r') as ds: if drifter_id == 'active' and ds.status != 'normal': continue elif drifter_id == 'inactive' and ds.status != 'inactive': continue elif drifter_id == 'not responding' and \ ds.status != 'not responding': continue buoy_id.append(ds.buoyid) lat.append(ds['latitude'][:]) lon.append(ds['longitude'][:]) status.append(ds.status) proj = pyproj.Proj(init=projection) view = _get_view(extent) res = [] for i, bid in enumerate(buoy_id): x, y = proj(lon[i], lat[i]) ls = LineString(zip(y, x)) if view.envelope.intersects(ls): path = np.array(ls.simplify(resolution * 1.5).coords) path = np.array( proj(path[:, 1], path[:, 0], inverse=True)).transpose() res.append({ 'type': "Feature", 'geometry': { 'type': "LineString", 'coordinates': path.astype(float).tolist() }, 'properties': { 'name': bid, 'status': status[i], 'type': "drifter", 'resolution': resolution, } }) result = { 'type': "FeatureCollection", 'features': res, } return result
def __init__(self, start, end, figure=None): self.start, self.end = start, end self.line = LineString([start, end]) self.figure = figure
def intersects_with(self, other_line: tuple): if self.figure and all( p in self.figure for p in other_line) and self.figure.crosses(other_line): return True return self.line.crosses(LineString(other_line))
def crosses(self, item): item = LineString(item) return any(item.crosses(e.line) for e in self.inner_edges)
def setUp(self): self.point = Point(1, 1) self.line1 = LineString(([0, 0], [2, 0])) self.line2 = LineString(([3, 0], [3, 6], [4.5, 6]))
def setup_method(self): self.t1 = Polygon([(0, 0), (1, 0), (1, 1)]) self.t2 = Polygon([(0, 0), (1, 1), (0, 1)]) self.t3 = Polygon([(2, 0), (3, 0), (3, 1)]) self.sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) self.t4 = Polygon([(0, 0), (3, 0), (3, 3), (0, 2)]) self.t5 = Polygon([(2, 0), (3, 0), (3, 3), (2, 3)]) self.inner_sq = Polygon( [(0.25, 0.25), (0.75, 0.25), (0.75, 0.75), (0.25, 0.75)] ) self.nested_squares = Polygon(self.sq.boundary, [self.inner_sq.boundary]) self.p0 = Point(5, 5) self.p3d = Point(5, 5, 5) self.g0 = GeoSeries( [ self.t1, self.t2, self.sq, self.inner_sq, self.nested_squares, self.p0, None, ] ) self.g1 = GeoSeries([self.t1, self.sq]) self.g2 = GeoSeries([self.sq, self.t1]) self.g3 = GeoSeries([self.t1, self.t2]) self.g3.crs = "epsg:4326" self.g4 = GeoSeries([self.t2, self.t1]) self.g4.crs = "epsg:4326" self.g_3d = GeoSeries([self.p0, self.p3d]) self.na = GeoSeries([self.t1, self.t2, Polygon()]) self.na_none = GeoSeries([self.t1, None]) self.a1 = self.g1.copy() self.a1.index = ["A", "B"] self.a2 = self.g2.copy() self.a2.index = ["B", "C"] self.esb = Point(-73.9847, 40.7484) self.sol = Point(-74.0446, 40.6893) self.landmarks = GeoSeries([self.esb, self.sol], crs="epsg:4326") self.l1 = LineString([(0, 0), (0, 1), (1, 1)]) self.l2 = LineString([(0, 0), (1, 0), (1, 1), (0, 1)]) self.g5 = GeoSeries([self.l1, self.l2]) self.g6 = GeoSeries([self.p0, self.t3]) self.g7 = GeoSeries([self.sq, self.t4]) self.g8 = GeoSeries([self.t1, self.t5]) self.empty = GeoSeries([]) self.all_none = GeoSeries([None, None]) self.empty_poly = Polygon() # Crossed lines self.l3 = LineString([(0, 0), (1, 1)]) self.l4 = LineString([(0, 1), (1, 0)]) self.crossed_lines = GeoSeries([self.l3, self.l4]) # Placeholder for testing, will just drop in different geometries # when needed self.gdf1 = GeoDataFrame( {"geometry": self.g1, "col0": [1.0, 2.0], "col1": ["geo", "pandas"]} ) self.gdf2 = GeoDataFrame( {"geometry": self.g1, "col3": [4, 5], "col4": ["rand", "string"]} ) self.gdf3 = GeoDataFrame( {"geometry": self.g3, "col3": [4, 5], "col4": ["rand", "string"]} )
print("Poly Bounding Box: ", world_bbox) #Poly Bounding Box: (-180.0, -90.0, 180.0, 90.0) print("Poly Exterior: ", world_ext) #NOT WORKING. OUTPUT should be : Poly Exterior: LINEARRING (-180 90, -180 -90, 180 -90, 180 90, -180 90) print("Poly Exterior Length: ", world_ext_length) #Poly Exterior Length: 1080.0 ''' # Create a MultiPoint object of our points 1,2 and 3 multi_point = MultiPoint([point1, point2, point3]) # It is also possible to pass coordinate tuples inside #multi_point2 = MultiPoint([(2.2, 4.2), (7.2, -25.1), (9.26, -2.456)]) # We can also create a MultiLineString with two lines line1 = LineString([point1, point2]) line2 = LineString([point2, point3]) multi_line = MultiLineString([line1, line2]) #print(line2) #print(multi_line) # MultiPolygon can be done in a similar manner # Let's divide our world into western and eastern hemispheres with a hole on the western hemisphere # -------------------------------------------------------------------------------------------------- # Let's create the exterior of the western part of the world west_exterior = [(-180, 90), (-180, -90), (0, -90), (0, 90)]
def perform_cut(P, e): """ Split up P into two polygons by cutting along e """ #print("Cut edge: %s"%(e,)) v = e[0] w = e[1] chain = LineString(P[0] + [P[0][0]]) #print("Chain to be cut: %s"%(chain,)) #print("Chain length: %7f"%chain.length) distance_to_v = chain.project(Point(v)) distance_to_w = chain.project(Point(w)) if distance_to_v == 0.0 and distance_to_w == 0.0: return (None, None) if distance_to_v == distance_to_w: return (None, None) #print("D_to_w: %7f, D_to_v: %2f"%(distance_to_w, distance_to_v)) if distance_to_w > distance_to_v: if round(distance_to_w, 4) >= round(chain.length, 4): # print("Special case") distance_to_v = chain.project(Point(v)) left_chain, right_chain = cut(chain, distance_to_v) p_l = left_chain.coords[:] if right_chain: p_r = right_chain.coords[:] else: p_r = [] else: if distance_to_v == 0: distance_to_w = chain.project(Point(w)) right_chain, remaining = cut(chain, distance_to_w) p_l = remaining.coords[:] p_r = right_chain.coords[:] else: cut_v_1, cut_v_2 = cut(chain, distance_to_v) distance_to_w = cut_v_2.project(Point(w)) right_chain, remaining = cut(cut_v_2, distance_to_w) p_l = cut_v_1.coords[:] + remaining.coords[:-1] p_r = right_chain.coords[:] else: if round(distance_to_v, 4) >= round(chain.length, 4): # print("Special case") distance_to_w = chain.project(Point(w)) right_chain, remaining = cut(chain, distance_to_w) p_l = remaining.coords[:] p_r = right_chain.coords[:] else: if distance_to_w == 0: distance_to_v = chain.project(Point(v)) right_chain, remaining = cut(chain, distance_to_v) p_l = remaining.coords[:] p_r = right_chain.coords[:] else: # print "here" #print chain cut_v_1, cut_v_2 = cut(chain, distance_to_w) #print("Cut1: %s"%cut_v_1) #print("Cut2: %s"%cut_v_2) distance_to_v = cut_v_2.project(Point(v)) # print("Dist: %2f. Length: %2f"%(distance_to_v, cut_v_2.length) ) right_chain, remaining = cut(cut_v_2, distance_to_v) # print remaining.coords[:] p_l = cut_v_1.coords[:] + remaining.coords[:-1] p_r = right_chain.coords[:] # p_l = right_chain.coords[:] # p_r = remaining.coords[:]+cut_v_1.coords[:] # print p_l, p_r return p_l, p_r
''' Find coordinate of Closest Point on Shapely LineString ''' from shapely.geometry import Point from shapely.geometry import LineString point = Point(0.0, 0.0) line = LineString([(-1, 0), (0, 1)]) dist = line.project(point) closest_point = line.interpolate(dist) print(closest_point)
from shapely.geometry import LineString from shapely.geometry import box import matplotlib.pyplot as plt from shapely.ops import linemerge def plot(ax, ob): try: x,y = ob.coords.xy except NotImplementedError: x,y = ob.exterior.xy plt.plot(x,y) fig, ax = plt.subplots() line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)]) plot(ax, line) bb = box(0.5,1.1,2.9,1.5) plot(ax, bb) result = line.intersection(bb) if len(result) > 1: for r in result: plot(ax, r)
def intersects_no_fly_zone(pointBefore, pointAfter): path_line_string = LineString([pointBefore, pointAfter]) for poly in no_fly_polygons: if path_line_string.intersects(poly): return True return False
def createConvexPath(self, pair): #pr = cProfile.Profile() #pr2 = cProfile.Profile() print pair[1] odPointsList = ((pair[0][0].x, pair[0][0].y), (pair[0][1].x, pair[0][1].y)) #st_line = LineString(odPointsList) labeledObstaclePoly = [] totalConvexPathList = {} dealtArcList = {} totalConvexPathList[odPointsList] = LineString(odPointsList) terminate = 0 idx_loop1 = 0 #sp_l_set = [] time_loop1 = 0 time_contain2 = 0 time_crossingDict = 0 time_convexLoop = 0 time_impedingArcs = 0 time_spatialFiltering = 0 time_loop1_crossingDict = 0 time_buildConvexHulls = 0 while terminate == 0: t1s = time.time() idx_loop1 += 1 t6s = time.time() w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') for line in totalConvexPathList: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "graph_" + str(idx_loop1) + self.version_name) totalGrpah = self.createGraph(totalConvexPathList.keys()) spatial_filter_n = networkx.dijkstra_path(totalGrpah, odPointsList[0], odPointsList[1]) spatial_filter = [] for i in xrange(len(spatial_filter_n)-1): spatial_filter.append([spatial_filter_n[i], spatial_filter_n[i+1]]) w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') for line in spatial_filter: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "spatial Filter_" + str(idx_loop1) + self.version_name) #sp_length = 0 #for j in spatial_filter: #sp_length += LineString(j).length #sp_l_set.append(sp_length) crossingDict = defaultdict(list) for line in spatial_filter: Line = LineString(line) for obs in self.obstaclesPolygons: if Line.crosses(obs): if obs not in labeledObstaclePoly: labeledObstaclePoly.append(obs) crossingDict[tuple(line)].append(obs) t6e = time.time() time_spatialFiltering += t6e - t6s if len(crossingDict.keys()) == 0: terminate = 1 continue else: t7s = time.time() for tLine in crossingDict.keys(): #cLine = list(tLine) if dealtArcList.has_key(tLine): try: del totalConvexPathList[tLine] except: del totalConvexPathList[(tLine[1], tLine[0])] continue else: dealtArcList[tLine] = LineString(list(tLine)) try: del totalConvexPathList[tLine] except: del totalConvexPathList[(tLine[1], tLine[0])] containingObs = [] for obs in crossingDict[tLine]: convexHull = self.createConvexhull(obs, tLine) self.splitBoundary(totalConvexPathList, convexHull) convexHull = self.createConvexhull(obs, odPointsList) self.splitBoundary(totalConvexPathList, convexHull) convexHull2 = self.createConvexhull(obs) if convexHull2.contains(Point(tLine[0])): containingObs.append(obs) elif convexHull2.contains(Point(tLine[1])): containingObs.append(obs) if len(containingObs) != 0: #SPLIT subConvexPathList = {} vi_obs = MultiPolygon([x for x in containingObs]) containedLineCoords = list(tLine) fromX = containedLineCoords[0][0] fromY = containedLineCoords[0][1] toX = containedLineCoords[1][0] toY = containedLineCoords[1][1] fxA = (fromY - toY) / (fromX - toX) fxB = fromY - (fxA * fromX) minX = vi_obs.bounds[0] maxX = vi_obs.bounds[2] split_line = LineString([(min(minX, fromX, toX), fxA * min(minX, fromX, toX) + fxB), (max(maxX, fromX, toX), fxA * max(maxX, fromX, toX) + fxB)]) for obs in containingObs: s1, s2 = self.splitPolygon(split_line, obs) dividedObsPoly = [] #to deal with multipolygon a = s1.intersection(obs) b = s2.intersection(obs) if a.type == "Polygon": dividedObsPoly.append(a) else: for o in a.geoms: if o.type == "Polygon": dividedObsPoly.append(o) if b.type == "Polygon": dividedObsPoly.append(b) else: for o2 in b.geoms: if o2.type == "Polygon": dividedObsPoly.append(o2) for obs2 in dividedObsPoly: for pt in tLine: convexHull = self.createConvexhull(obs2, [pt]) self.splitBoundary(subConvexPathList, convexHull) subVertices = [] for line in subConvexPathList: subVertices.extend(line) subVertices = list(set(subVertices)) containingObsVertices = [] for obs in containingObs: containingObsVertices.extend(list(obs.exterior.coords)) subVertices = [x for x in subVertices if x in containingObsVertices] deleteList = [] for line in subConvexPathList: chk_cross = 0 for obs in containingObs: if subConvexPathList[line].crosses(obs): chk_cross = 1 if chk_cross == 1: deleteList.append(line) for line in deleteList: del subConvexPathList[line] #subConvexPathList.remove(line) pairList = [] for i in range(len(subVertices)): for j in range(i+1, len(subVertices)): pairList.append((subVertices[i], subVertices[j])) for i in pairList: Line = LineString(i) chk_cross = 0 for obs in containingObs: if Line.crosses(obs): chk_cross = 1 elif Line.within(obs): chk_cross = 1 if chk_cross == 0: subConvexPathList[i] = Line #subConvexPathList.append(i) buffer_st_line = split_line.buffer(0.1) deleteList = [] for line in subConvexPathList: if buffer_st_line.contains(subConvexPathList[line]): deleteList.append(line) for line in deleteList: if subConvexPathList.has_key(line): del subConvexPathList[line] #subConvexPathList = [x for x in subConvexPathList if x not in deleteList] for line in subConvexPathList: if not totalConvexPathList.has_key(line): if not totalConvexPathList.has_key((line[1],line[0])): totalConvexPathList[line] = subConvexPathList[line] #if line not in totalConvexPathList: #if [line[1], line[0]] not in totalConvexPathList: #totalConvexPathList.append(line) w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') for line in totalConvexPathList: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "graph2_" + str(idx_loop1) + self.version_name) t7e = time.time() time_loop1_crossingDict += t7e - t7s #new lines labeled_multyPoly = MultiPolygon([x for x in labeledObstaclePoly]) convexHull = self.createConvexhull(labeled_multyPoly, odPointsList) self.splitBoundary(totalConvexPathList, convexHull) #new lines end #impededPathList t5s = time.time() impededPathList = {} for line in totalConvexPathList: for obs in labeledObstaclePoly: if totalConvexPathList[line].crosses(obs): impededPathList[line] = totalConvexPathList[line] break t5e = time.time() time_impedingArcs += t5e - t5s for line in impededPathList: del totalConvexPathList[line] terminate2 = 0 idx_loop2 = 0 t1e = time.time() time_loop1 += t1e - t1s #w = shapefile.Writer(shapefile.POLYGON) #w.field('net') #for obs in labeledObstaclePoly: #w.poly(parts=[[list(x) for x in list(obs.exterior.coords)]]) #w.record('ff') #w.save(self.path + "obs"+ str(idx_loop1) + "_" + self.version_name) while terminate2 == 0: idx_loop2 += 1 deleteList = [] crossingDict = defaultdict(list) for line in dealtArcList: if impededPathList.has_key(line): del impededPathList[line] elif impededPathList.has_key((line[1], line[0])): del impededPathList[(line[1],line[0])] t3s = time.time() #pr.enable() for line in impededPathList: for obs in labeledObstaclePoly: if impededPathList[line].crosses(obs): crossingDict[line].append(obs) t3e = time.time() time_crossingDict += t3e - t3s #at this point, impededArcList should be emptied, as it only contains crossing arcs, and all of them #should be replaced by convex hulls. for line in crossingDict: del impededPathList[line] for line in impededPathList: if not totalConvexPathList.has_key(line): totalConvexPathList[line] = impededPathList[line] impededPathList = {} if len(crossingDict.keys()) == 0: terminate2 = 1 continue else: #w = shapefile.Writer(shapefile.POLYLINE) #w.field('nem') #for line in crossingDict: #w.line(parts=[[ list(x) for x in line ]]) #w.record('ff') #w.save(self.path + "crossingDict_" + str(idx_loop1) + "_"+ str(idx_loop2) +"_"+ self.version_name) t4s = time.time() for tLine in crossingDict.keys(): dealtArcList[tLine] = crossingDict[tLine] containingObs = [] for obs in crossingDict[tLine]: chk_contain = 0 convexHull2 = self.createConvexhull(obs) if convexHull2.contains(Point(tLine[0])): containingObs.append(obs) chk_contain = 1 elif convexHull2.contains(Point(tLine[1])): containingObs.append(obs) chk_contain = 1 if chk_contain == 0: t10s = time.time() convexHull = self.createConvexhull(obs, tLine) self.splitBoundary(impededPathList, convexHull) t10e = time.time() time_buildConvexHulls += t10e - t10s if len(containingObs) != 0: #SPLIT #print "SPLIT" t2s = time.time() subConvexPathList = {} vi_obs = MultiPolygon([x for x in containingObs]) containedLineCoords = tLine fromX = containedLineCoords[0][0] fromY = containedLineCoords[0][1] toX = containedLineCoords[1][0] toY = containedLineCoords[1][1] fxA = (fromY - toY) / (fromX - toX) fxB = fromY - (fxA * fromX) minX = vi_obs.bounds[0] maxX = vi_obs.bounds[2] split_line = LineString([(min(minX, fromX, toX), fxA * min(minX, fromX, toX) + fxB), (max(maxX, fromX, toX), fxA * max(maxX, fromX, toX) + fxB)]) for obs in containingObs: s1, s2 = self.splitPolygon(split_line, obs) dividedObsPoly = [] #to deal with multipolygon a = s1.intersection(obs) b = s2.intersection(obs) if a.type == "Polygon": dividedObsPoly.append(a) else: for o in a.geoms: if o.type == "Polygon": dividedObsPoly.append(o) if b.type == "Polygon": dividedObsPoly.append(b) else: for o2 in b.geoms: if o2.type == "Polygon": dividedObsPoly.append(o2) for obs2 in dividedObsPoly: for pt in tLine: convexHull = self.createConvexhull(obs2, [pt]) self.splitBoundary(subConvexPathList, convexHull) subVertices = [] for line in subConvexPathList: subVertices.extend(line) subVertices = list(set(subVertices)) containingObsVertices = [] for obs in containingObs: containingObsVertices.extend(list(obs.exterior.coords)) subVertices = [x for x in subVertices if x in containingObsVertices] deleteList = [] for line in subConvexPathList: chk_cross = 0 for obs in containingObs: if subConvexPathList[line].crosses(obs): chk_cross = 1 if chk_cross == 1: deleteList.append(line) for line in deleteList: del subConvexPathList[line] pairList = [] for i in range(len(subVertices)): for j in range(i+1, len(subVertices)): pairList.append((subVertices[i], subVertices[j])) for i in pairList: Line = LineString(list(i)) chk_cross = 0 for obs in containingObs: if Line.crosses(obs): chk_cross = 1 elif Line.within(obs): chk_cross = 1 if chk_cross == 0: subConvexPathList[i] = Line buffer_st_line = split_line.buffer(0.1) deleteList = [] for line in subConvexPathList: if buffer_st_line.contains(subConvexPathList[line]): deleteList.append(line) for line in deleteList: del subConvexPathList[line] for line in subConvexPathList: if not impededPathList.has_key(line): if not impededPathList.has_key((line[1], line[0])): impededPathList[line] = subConvexPathList[line] t2e = time.time() time_contain2 += t2e - t2s #pr.disable() for line in dealtArcList: if impededPathList.has_key(line): del impededPathList[line] #impededPathList = [x for x in impededPathList if x not in dealtArcList] t4e = time.time() time_convexLoop += t4e - t4s #end of else w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') for line in impededPathList: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "After_graph_" + str(idx_loop1) + "_"+ str(idx_loop2) +"_"+ self.version_name) #end of while2 for line in impededPathList: if not totalConvexPathList.has_key(line): totalConvexPathList[line] = impededPathList[line] #totalConvexPathList.extend(impededPathList) totalGraph = self.createGraph(totalConvexPathList.keys()) esp_n = networkx.dijkstra_path(totalGraph, odPointsList[0], odPointsList[1]) esp = [] for i in range(len(esp_n)-1): esp.append([esp_n[i], esp_n[i+1]]) w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') no_edges = 0 for line in totalConvexPathList.keys(): no_edges += 1 w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "totalpath" + self.version_name + "%d" % pair[1] ) w = shapefile.Writer(shapefile.POLYLINE) w.field('nem') for line in esp: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') w.save(self.path + "ESP_" + self.version_name + "%d" % pair[1]) #sp_len_str = str(sp_l_set)[1:-1] #s = StringIO.StringIO() #sortby = 'cumulative' #ps = pstats.Stats(pr, stream=s).sort_stats(sortby) #ps.print_stats() #print s.getvalue() # # s = StringIO.StringIO() # sortby = 'cumulative' # ps = pstats.Stats(pr2, stream=s).sort_stats(sortby) # ps.print_stats() # print s.getvalue() print "loop1: ", time_loop1 print "Spatial Filtering: ", time_spatialFiltering print "loop1 crossingDict: ", time_loop1_crossingDict print "crossingDict: ", time_crossingDict print 'convexLoop: ', time_convexLoop print "time_contain: ", time_contain2 print "impedingArcs: ", time_impedingArcs print "convexHUll: ", time_buildConvexHulls return 'convexpath %d %d %d %f %f %f' % (pair[1], no_edges, len(labeledObstaclePoly), time_convexLoop, time_crossingDict, time_buildConvexHulls)
def from_ordered_shadow_and_cut_pt_coords(cls, x_min_max=None, y_ground=Y_GROUND, ordered_shadow_coords=[], cut_point_coords=[], param_names=[], shaded_params={}, illum_params={}): """Build a horizontal flat ground surface, made of 1 PVSegment with shaded areas and "cut points" (reference points used in view factor calculations) Parameters ---------- x_min_max : tuple, optional List of minimum and maximum x coordinates for the flat surface [m] (Default = None) y_ground : float, optional Location of flat ground on y axis in [m] (Default = Y_GROUND) ordered_shadow_coords : list, optional List of shadow coordinates, ordered from left to right. Shape = (# of shadows, 2 {# of points}, 2 {for xy coords}) (Default = []) cut_point_coords : list, optional List of cut point coordinates, ordered from left to right. Shape = (# of cut points, 2 {# of points}, 2 {for xy coords}) (Default = []) param_names : list of str, optional Names of the surface parameters, eg reflectivity, total incident irradiance, temperature, etc. (Default = []) shaded_params : dict, optional Dictionary of parameter values for shaded surfaces (Default = {}) illum_params : dict, optional Dictionary of parameter values for illuminated surfaces (Default = {}) Returns ------- PVGround object PV ground with shadows, illuminated ground, and cut points """ # Get ground boundaries if x_min_max is None: x_min, x_max = MIN_X_GROUND, MAX_X_GROUND else: x_min, x_max = x_min_max full_extent_coords = [(x_min, y_ground), (x_max, y_ground)] # Create the list of illuminated and shaded PV surfaces list_shaded_surfaces = [] list_illum_surfaces = [] recurse_on_cut_points(list_shaded_surfaces, list_illum_surfaces, ordered_shadow_coords, cut_point_coords, x_min, x_max, y_ground, param_names, shaded_params, illum_params) # Create the shade collections shaded_collection = ShadeCollection(list_surfaces=list_shaded_surfaces, shaded=True, param_names=param_names) illum_collection = ShadeCollection(list_surfaces=list_illum_surfaces, shaded=False, param_names=param_names) # Create the ground segment segment = PVSegment(illum_collection=illum_collection, shaded_collection=shaded_collection) return cls(list_segments=[segment], original_linestring=LineString(full_extent_coords))
def polygons_to_geom_dicts(polygons, skip_invalid=True): """ Converts a Polygons element into a list of geometry dictionaries, preserving all value dimensions. For array conversion the following conventions are applied: * Any nan separated array are converted into a MultiPolygon * Any array without nans is converted to a Polygon * If there are holes associated with a nan separated array the holes are assigned to the polygons by testing for an intersection * If any single array does not have at least three coordinates it is skipped by default * If skip_invalid=False and an array has less than three coordinates it will be converted to a LineString """ interface = polygons.interface.datatype if interface == 'geodataframe': return [row.to_dict() for _, row in polygons.data.iterrows()] elif interface == 'geom_dictionary': return [polygons.data] elif interface == 'multitabular' and all(isinstance(p, dict) and 'geometry' in p for p in polygons.data): return polygons.data polys = [] xdim, ydim = polygons.kdims has_holes = polygons.has_holes holes = polygons.holes() if has_holes else None for i, polygon in enumerate(polygons.split(datatype='columns')): array = np.column_stack([polygon.pop(xdim.name), polygon.pop(ydim.name)]) splits = np.where(np.isnan(array[:, :2].astype('float')).sum(axis=1))[0] arrays = np.split(array, splits+1) if len(splits) else [array] invalid = False subpolys = [] subholes = None if has_holes: subholes = [[LinearRing(h) for h in hs] for hs in holes[i]] for j, arr in enumerate(arrays): if j != (len(arrays)-1): arr = arr[:-1] # Drop nan if len(arr) == 0: continue elif len(arr) == 1: if skip_invalid: continue poly = Point(arr[0]) invalid = True elif len(arr) == 2: if skip_invalid: continue poly = LineString(arr) invalid = True elif not len(splits): poly = Polygon(arr, (subholes[j] if has_holes else [])) else: poly = Polygon(arr) hs = [h for h in subholes[j]] if has_holes else [] poly = Polygon(poly.exterior, holes=hs) subpolys.append(poly) if invalid: polys += [dict(polygon, geometry=sp) for sp in subpolys] continue elif len(subpolys) == 1: geom = subpolys[0] elif subpolys: geom = MultiPolygon(subpolys) else: continue polygon['geometry'] = geom polys.append(polygon) return polys
def createGraph(self, lineSet): resultingGraph = networkx.Graph() for line in lineSet: resultingGraph.add_edge(line[0], line[1], weight = LineString(list(line)).length) return resultingGraph
def main(): config = load_config() inland_edge_file = os.path.join( config['paths']['data'], 'Results', 'Flow_shapefiles', 'weighted_edges_flows_national_inland.shp') color = '#0689d7' color_by_type = {'Inland Line': color} crop_cols = [ 'max_rice', 'max_cash', 'max_cass', 'max_teas', 'max_maiz', 'max_rubb', 'max_swpo', 'max_acof', 'max_rcof', 'max_pepp' ] ind_cols = [ 'max_sugar', 'max_wood', 'max_steel', 'max_constr', 'max_cement', 'max_fertil', 'max_coal', 'max_petrol', 'max_manufa', 'max_fisher', 'max_meat', 'max_tons' ] columns = crop_cols + ind_cols column_label_divisors = {c: 1 for c in columns} legend_label = "AADF (tons/day)" title_cols = [ 'Rice', 'Cashew', 'Cassava', 'Teas', 'Maize', 'Rubber', 'Sweet Potatoes', 'Coffee Arabica', 'Coffee Robusta', 'Pepper', 'Sugar', 'Wood', 'Steel', 'Construction materials', 'Cement', 'Fertilizer', 'Coal', 'Petroleum', 'Manufacturing', 'Fishery', 'Meat', 'Total tonnage' ] remove_routes_ids = [ ('watern_149', 'watern_429'), ('watern_429', 'watern_520'), ('watern_700', 'watern_520'), ('watern_210', 'watern_700'), ('watern_209', 'watern_210'), ('watern_1057', 'watern_1050'), ('watern_1050', 'watern_1051'), ('watern_1051', 'watern_183'), ('watern_183', 'watern_354'), ('watern_176', 'watern_354'), ] for c in range(len(columns)): ax = get_axes() plot_basemap(ax, config['paths']['data']) scale_bar(ax, location=(0.8, 0.05)) plot_basemap_labels(ax, config['paths']['data']) proj_lat_lon = ccrs.PlateCarree() column = columns[c] weights = [ record.attributes[column] for record in shpreader.Reader(inland_edge_file).records() ] max_weight = max(weights) width_by_range = generate_weight_bins(weights) geoms_by_range = {} for value_range in width_by_range: geoms_by_range[value_range] = [] for record in shpreader.Reader(inland_edge_file).records(): val = record.attributes[column] geom = record.geometry edge_id = (record.attributes['from_node'], record.attributes['to_node']) if val > 0 and (edge_id not in remove_routes_ids ): #only add edges that carry this commodity for nmin, nmax in geoms_by_range: if nmin <= val and val < nmax: geoms_by_range[(nmin, nmax)].append(geom) # plot for range_, width in width_by_range.items(): ax.add_geometries( [geom.buffer(width) for geom in geoms_by_range[range_]], crs=proj_lat_lon, edgecolor='none', facecolor=color, zorder=2) x_l = 102.3 x_r = x_l + 0.4 base_y = 14 y_step = 0.4 y_text_nudge = 0.1 x_text_nudge = 0.1 ax.text(x_l, base_y + y_step - y_text_nudge, legend_label, horizontalalignment='left', transform=proj_lat_lon, size=10) divisor = column_label_divisors[column] for (i, ((nmin, nmax), width)) in enumerate(width_by_range.items()): y = base_y - (i * y_step) line = LineString([(x_l, y), (x_r, y)]) ax.add_geometries([line.buffer(width)], crs=proj_lat_lon, linewidth=0, edgecolor=color, facecolor=color, zorder=2) if nmin == max_weight: label = '>{:.2f}'.format(max_weight / divisor) else: label = '{:.2f}-{:.2f}'.format(nmin / divisor, nmax / divisor) ax.text(x_r + x_text_nudge, y - y_text_nudge, label, horizontalalignment='left', transform=proj_lat_lon, size=10) plt.title(title_cols[c], fontsize=14) output_file = os.path.join(config['paths']['figures'], 'inland_flow-map-{}.png'.format(column)) save_fig(output_file) plt.close()
def find_cut_space(P, v, is_reflex=True): """ Generate the cut space at v using Visilibity library. """ # print v c_of_b = cone_of_bisection.compute(P, v, is_reflex=is_reflex) c_of_b = Polygon(c_of_b) P = Polygon(*P) # Debug visualization # Plot the polygon itself # import pylab as p # x, y = P.exterior.xy # p.plot(x, y) # x, y = c_of_b.exterior.xy # p.plot(x, y) # p.show() # print P.is_valid #print P #print c_of_b intersection = c_of_b.intersection(P) #print("Intersection: %s"%intersection) intersection = get_closest_intersecting_polygon(intersection, v) #print("Closest Intersection object: %s"%(intersection,)) P_vis = [] vis_holes = [] P_vis.append(intersection.exterior.coords[:]) for hole in intersection.interiors: vis_holes.append(hole.coords[:]) P_vis.append(vis_holes) #print P_vis point_x, point_y = visib_polyg.compute(v, P_vis) #print point_x, point_y # point_x, point_y = visib_polyg.compute(v, [P.exterior.coords[:],[]]) visible_polygon = Polygon(zip(point_x, point_y)) # print("Visible polygon: %s"%(visible_polygon,)) # Debug visualization # Plot the polygon itself # import pylab as p # x, y = P.exterior.xy # p.plot(x, y) #x, y = c_of_b.exterior.xy #p.plot(x, y) #x, y = intersection.exterior.xy #p.plot(x, y) # p.plot(point_x, point_y) # p.show() # At this point, we have visibility polygon. # Now we need to find edges of visbility polygon which are on the boundary #visible_polygon = shapely.geometry.polygon.orient(Polygon(zip(point_x, point_y)),-1) visible_polygon_ls = LineString(visible_polygon.exterior.coords[:]) visible_polygon_ls_buffer = visible_polygon_ls.buffer(BUFFER_RADIUS) ext_ls = LineString(P.exterior) holes_ls = [] for interior in P.interiors: holes_ls.append(LineString(interior)) # Start adding cut space on the exterior cut_space = [] common_items = [] #common_items = ext_ls.intersection(visible_polygon_ls) common_items = ext_ls.intersection( visible_polygon_ls_buffer) # Buffer gives better results # print("Common item: %s"%(common_items,)) # Filter out very small segments # Add environment first if common_items.geom_type == "MultiLineString": for element in common_items: line = element.coords[:] # Examine each edge of the linestring for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif common_items.geom_type == "LineString": # Examine each edge of the linestring line = common_items.coords[:] for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif common_items.geom_type == "GeometryCollection": for item in common_items: if item.geom_type == "MultiLineString": for element in item: line = element.coords[:] # Examine each edge of the linestring for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif item.geom_type == "LineString": # Examine each edge of the linestring line = item.coords[:] for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) # print("One iteration of cut: %s"%(cut_space,)) ## Now start adding the hole boundaries for interior in P.interiors: common_items = interior.intersection(visible_polygon_ls_buffer) if common_items.geom_type == "LineString": line = common_items.coords[:] for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif common_items.geom_type == "MultiLineString": for element in common_items: line = element.coords[:] # Examine each edge of the linestring for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif common_items.geom_type == "GeometryCollection": for item in common_items: if item.geom_type == "LineString": line = item.coords[:] for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) elif item.geom_type == "MultiLineString": for element in item: line = element.coords[:] # Examine each edge of the linestring for i in range(len(line) - 1): edge = line[i:i + 2] edge_ls = LineString(edge) if edge_ls.length > LINE_LENGTH_THRESHOLD: cut_space.append(edge) # cut_space could be lines our of order in no particular direciton # We want the cut space to be cw oriented # First form a list of points # temp_points_list = [] # for line in cut_space: # temp_points_list.append(line[0]); temp_points_list.append(line[1]) # # # Form a polygon with the exterior the points geenrated above # temp_poly = Polygon(temp_points_list) # # # Orient the polygon's exterior clockwise # orient(temp_poly, sign=-1) # # # Form the final oriented cut space chain # cut_space_ring = temp_poly.exterior.coords[:-1] # print("Cut Space: %s:"%(cut_space,)) # cut_space_chain = [] # cut_space_chain.append(cut_space[0][0]) # for line in cut_space: # cut_space_chain.append(line[1]) # # if LinearRing(cut_space_chain+[v[1]]).is_ccw: # cut_space_ring = cut_space_chain[::-1] # else: # cut_space_ring = cut_space_chain[:] # print cut_space_ring # PLOTTING # import pylab as p # # Plot the polygon itself # x, y = P.exterior.xy # p.plot(x, y) # # plot the intersection of the cone with the polygon # intersection_x, intersection_y = intersection.exterior.xy # p.plot(intersection_x, intersection_y) # p.show() #print cut_space # return cut_space_ring return cut_space
def connect_assets_to_elec_nodes(): """ Affiliate local assets with their nearest electricity node. """ path = os.path.join(DATA_INTERMEDIATE, 'elec_distribution.shp') elec_sites = gpd.read_file(path) path = os.path.join(DATA_INTERMEDIATE, 'gas_sites.shp') gas_sites = gpd.read_file(path) path = os.path.join(DATA_INTERMEDIATE, 'airports.shp') airports = gpd.read_file(path) path = os.path.join(DATA_INTERMEDIATE, 'railway_stations.shp') railway_stations = gpd.read_file(path) sites = gas_sites.append(airports) sites = sites.append(railway_stations) output_edges = [] output_nodes = [] for idx, site in sites.iterrows(): nearest = nearest_points(site['geometry'], elec_sites.unary_union)[1] geom = LineString([ (site['geometry'].coords[0][0], site['geometry'].coords[0][1]), (nearest.coords[0][0], nearest.coords[0][1]), ]) nearest = gpd.GeoDataFrame({'geometry': [nearest]}, index=[idx], crs='epsg:27700') nearest['geometry'] = nearest['geometry'].buffer(10) elec_site = gpd.overlay(elec_sites, nearest, how='intersection') output_edges.append({ 'geometry': geom, 'properties': { 'origin_id': elec_site['id'][0], 'dest_funth': site['functionth'], 'dest_func': site['function'], 'dest_dist': site['distinctiv'], }, }) output_nodes.append({ 'geometry': site['geometry'], 'properties': { 'origin_id': elec_site['id'][0], 'dest_funth': site['functionth'], 'dest_func': site['function'], 'dest_dist': site['distinctiv'], }, }) output_edges = gpd.GeoDataFrame.from_features(output_edges, crs='epsg:27700') path = os.path.join(DATA_INTERMEDIATE, 'network_edges.shp') output_edges.to_file(path, crs='epsg:27700') output_nodes = gpd.GeoDataFrame.from_features(output_nodes, crs='epsg:27700') path = os.path.join(DATA_INTERMEDIATE, 'network_nodes.shp') output_nodes.to_file(path, crs='epsg:27700')
def simplify_graph(nodes_gdf, edges_gdf): """ The function identify pseudo-nodes, namely nodes that represent intersection between only 2 segments. The segments are merged and the node is removed from the nodes_gdf GeoDataFrame. Parameters ---------- nodes_gdf: Point GeoDataFrame nodes (junctions) GeoDataFrame edges_gdf: LineString GeoDataFrame street segments GeoDataFrame Returns ------- nodes_gdf, edges_gdf: tuple of GeoDataFrames the cleaned junctions and street segments GeoDataFrame """ nodes_gdf, edges_gdf = nodes_gdf.copy(), edges_gdf.copy() # editing the nodes which only connect two edges to_edit = {k: v for k, v in nodes_degree(edges_gdf).items() if v == 2} if len(to_edit) == 0: return (nodes_gdf, edges_gdf) to_edit_list = list(to_edit.keys()) if 'stationID' in nodes_gdf.columns: tmp_nodes = nodes_gdf[(nodes_gdf.nodeID.isin(to_edit_list)) & (nodes_gdf.stationID == 999999)].copy() to_edit_list = list(tmp_nodes.nodeID.values) if len(to_edit_list) == 0: return (nodes_gdf, edges_gdf) for nodeID in to_edit_list: tmp = edges_gdf[(edges_gdf['u'] == nodeID) | (edges_gdf['v'] == nodeID)].copy() if len(tmp) == 0: nodes_gdf.drop(nodeID, axis=0, inplace=True) continue if len(tmp) == 1: continue # possible dead end # dead end identified index_first, index_second = tmp.iloc[0].edgeID, tmp.iloc[ 1].edgeID # first segment index # Identifying the relationship between the two segments. # New node_u and node_v are assigned accordingly. A list of ordered coordinates is obtained for # merging the geometries. 4 conditions: if (tmp.iloc[0]['u'] == tmp.iloc[1]['u']): edges_gdf.at[index_first, 'u'] = edges_gdf.loc[index_first]['v'] edges_gdf.at[index_first, 'v'] = edges_gdf.loc[index_second]['v'] line_coordsA, line_coordsB = list( tmp.iloc[0]['geometry'].coords), list( tmp.iloc[1]['geometry'].coords) line_coordsA.reverse() elif (tmp.iloc[0]['u'] == tmp.iloc[1]['v']): edges_gdf.at[index_first, 'u'] = edges_gdf.loc[index_second]['u'] line_coordsA, line_coordsB = list( tmp.iloc[1]['geometry'].coords), list( tmp.iloc[0]['geometry'].coords) elif (tmp.iloc[0]['v'] == tmp.iloc[1]['u']): edges_gdf.at[index_first, 'v'] = edges_gdf.loc[index_second]['v'] line_coordsA, line_coordsB = list( tmp.iloc[0]['geometry'].coords), list( tmp.iloc[1]['geometry'].coords) else: # (tmp.iloc[0]['v'] == tmp.iloc[1]['v']) edges_gdf.at[index_first, 'v'] = edges_gdf.loc[index_second]['u'] line_coordsA, line_coordsB = list( tmp.iloc[0]['geometry'].coords), list( tmp.iloc[1]['geometry'].coords) line_coordsB.reverse() # checking that none edges with node_u == node_v have been created, if yes: drop them if edges_gdf.loc[index_first].u == edges_gdf.loc[index_first].v: edges_gdf.drop([index_first, index_second], axis=0, inplace=True) nodes_gdf.drop(nodeID, axis=0, inplace=True) continue # obtaining coordinates-list in consistent order and merging new_line = line_coordsA + line_coordsB merged_line = LineString([coor for coor in new_line]) edges_gdf.at[index_first, 'geometry'] = merged_line if 'highway' in edges_gdf.columns: #type of street if edges_gdf.loc[index_second]['pedestrian']: edges_gdf.at[index_first, 'pedestrian'] = 1 # dropping the second segment, as the new geometry was assigned to the first edge edges_gdf.drop(index_second, axis=0, inplace=True) nodes_gdf.drop(nodeID, axis=0, inplace=True) return nodes_gdf, edges_gdf
coast_distance = 0 for line in f: line.strip() columns = line.split() B_lon = columns[0] B_lat = columns[1] E_lon = columns[2] E_lat = columns[3] # Convert lat/lon to map projection coordinates B_x, B_y = m(B_lon, B_lat) E_x, E_y = m(E_lon, E_lat) # Make the line end coordinates into linestring object perp_line = LineString(((B_x, B_y), (E_x, E_y))) # Get interpolated line_x = [] line_y = [] for iinterp in range(11): interp = iinterp / 10 line = perp_line.interpolate(interp, normalized=True).xy line_x.append(tuple(line)[0][0]) line_y.append(tuple(line)[1][0]) # Convert projection x,y coords to lon/lat line_lon, line_lat = m(line_x, line_y, inverse=True) # Convert -180:180 to 0:360 line_lon = np.array(line_lon)
# Request normal route between appropriate locations without construction sites request_params = { 'coordinates': [[12.108259, 54.081919], [12.072063, 54.103684]], 'format_out': 'geojson', 'profile': 'driving-car', 'preference': 'shortest', 'instructions': 'false', } route_normal = ors.directions(**request_params) folium.features.GeoJson(data=route_normal, name='Route without construction sites', style_function=style_function('#FF0000'), overlay=True).add_to(map2) # Buffer route with 0.009 degrees (really, just too lazy to project again...) route_buffer = LineString( route_normal['features'][0]['geometry']['coordinates']).buffer(0.009) folium.features.GeoJson(data=geometry.mapping(route_buffer), name='Route Buffer', style_function=style_function('#FFFF00'), overlay=True).add_to(map2) # Plot which construction sites fall into the buffer Polygon sites_buffer_poly = [] for site_poly in sites_poly: poly = Polygon(site_poly) if route_buffer.intersects(poly): folium.features.Marker(list(reversed( poly.centroid.coords[0]))).add_to(map2) sites_buffer_poly.append(poly) map2
def compare_thalweg(args): huc_dir = args[0] stream_type = args[1] point_density = args[2] huc = args[3] dem_meters_filename = args[4] dem_lateral_thalweg_adj_filename = args[5] dem_thalwegCond_filename = args[6] profile_plots_filename = args[7] profile_gpkg_filename = args[8] profile_table_filename = args[9] flows_grid_boolean_filename = args[10] if stream_type == 'derived': dem_derived_reaches_filename = os.path.join( huc_dir, 'demDerived_reaches_split.gpkg') streams = gpd.read_file(dem_derived_reaches_filename) nhd_headwater_filename = os.path.join( huc_dir, 'nhd_headwater_points_subset.gpkg') wbd_filename = os.path.join(huc_dir, 'wbd.gpkg') wbd = gpd.read_file(wbd_filename) headwaters_layer = gpd.read_file(nhd_headwater_filename, mask=wbd) headwater_list = headwaters_layer.loc[headwaters_layer.pt_type == 'nws_lid'] stream_id = 'HydroID' elif stream_type == 'burnline': nhd_reaches_filename = os.path.join( huc_dir, 'NHDPlusBurnLineEvent_subset.gpkg') nhd_reaches = gpd.read_file(nhd_reaches_filename) streams = nhd_reaches.copy() headwaters_layer = None # Get lists of all complete reaches using headwater attributes headwater_list = streams.loc[streams.nws_lid != ''].nws_lid stream_id = 'NHDPlusID' headwater_col = 'is_headwater' streams[headwater_col] = False headwater_list = headwater_list.reset_index(drop=True) if stream_type == 'derived': streams['nws_lid'] = '' if streams.NextDownID.dtype != 'int': streams.NextDownID = streams.NextDownID.astype(int) min_dist = np.empty(len(headwater_list)) streams['min_dist'] = 1000 for i, point in headwater_list.iterrows(): streams['min_dist'] = [ point.geometry.distance(line) for line in streams.geometry ] streams.loc[streams.min_dist == np.min(streams.min_dist), 'nws_lid'] = point.site_id headwater_list = headwater_list.site_id streams.set_index(stream_id, inplace=True, drop=False) # Collect headwater streams single_stream_paths = [] dem_meters = rasterio.open(dem_meters_filename, 'r') index_option = 'reachID' for index, headwater_site in enumerate(headwater_list): stream_path = get_downstream_segments(streams.copy(), 'nws_lid', headwater_site, 'downstream', stream_id, stream_type) stream_path = stream_path.reset_index(drop=True) stream_path = stream_path.sort_values(by=['downstream_count']) stream_path = stream_path.loc[stream_path.downstream == True] if stream_type == 'burnline': geom_value = [] for index, segment in stream_path.iterrows(): lineString = LineString(segment.geometry.coords[::-1]) geom_value = geom_value + [ (lineString, segment.downstream_count) ] nhd_reaches_raster = features.rasterize( shapes=geom_value, out_shape=[dem_meters.height, dem_meters.width], fill=dem_meters.nodata, transform=dem_meters.transform, all_touched=True, dtype=np.float32) flow_bool = rasterio.open(flows_grid_boolean_filename) flow_bool_data = flow_bool.read(1) nhd_reaches_raster = np.where(flow_bool_data == int(0), -9999.0, (nhd_reaches_raster).astype( rasterio.float32)) out_dem_filename = os.path.join(huc_dir, 'NHDPlusBurnLineEvent_raster.tif') with rasterio.open(out_dem_filename, "w", **dem_meters.profile, BIGTIFF='YES') as dest: dest.write(nhd_reaches_raster, indexes=1) stream_path = convert_grid_cells_to_points(out_dem_filename, index_option) stream_path["headwater_path"] = headwater_site single_stream_paths = single_stream_paths + [stream_path] print(f"length of {headwater_site} path: {len(stream_path)}") # Collect elevation values from multiple grids along each individual reach point dem_lateral_thalweg_adj = rasterio.open(dem_lateral_thalweg_adj_filename, 'r') dem_thalwegCond = rasterio.open(dem_thalwegCond_filename, 'r') thalweg_points = gpd.GeoDataFrame() for path in single_stream_paths: split_points = [] stream_ids = [] dem_m_elev = [] dem_burned_filled_elev = [] dem_lat_thal_adj_elev = [] dem_thal_adj_elev = [] headwater_path = [] index_count = [] for index, segment in path.iterrows(): if stream_type == 'derived': linestring = segment.geometry if point_density == 'midpoints': midpoint = linestring.interpolate(0.5, normalized=True) stream_ids = stream_ids + [segment[stream_id]] split_points = split_points + [midpoint] index_count = index_count + [segment.downstream_count] dem_m_elev = dem_m_elev + [ np.array( list( dem_meters.sample((Point(midpoint).coords), indexes=1))).item() ] dem_lat_thal_adj_elev = dem_lat_thal_adj_elev + [ np.array( list( dem_lateral_thalweg_adj.sample( (Point(midpoint).coords), indexes=1))).item() ] dem_thal_adj_elev = dem_thal_adj_elev + [ np.array( list( dem_thalwegCond.sample( (Point(midpoint).coords), indexes=1))).item() ] headwater_path = headwater_path + [segment.headwater_path] elif point_density == 'all_points': count = 0 for point in zip(*linestring.coords.xy): stream_ids = stream_ids + [segment[stream_id]] split_points = split_points + [Point(point)] count = count + 1 index_count = index_count + [ segment.downstream_count * 1000 + count ] dem_m_elev = dem_m_elev + [ np.array( list( dem_meters.sample((Point(point).coords), indexes=1))).item() ] dem_lat_thal_adj_elev = dem_lat_thal_adj_elev + [ np.array( list( dem_lateral_thalweg_adj.sample( (Point(point).coords), indexes=1))).item() ] dem_thal_adj_elev = dem_thal_adj_elev + [ np.array( list( dem_thalwegCond.sample( (Point(point).coords), indexes=1))).item() ] headwater_path = headwater_path + [ segment.headwater_path ] elif stream_type == 'burnline': stream_ids = stream_ids + [segment['id']] split_points = split_points + [Point(segment.geometry)] index_count = index_count + [segment['id']] dem_m_elev = dem_m_elev + [ np.array( list( dem_meters.sample((Point(segment.geometry).coords), indexes=1))).item() ] dem_lat_thal_adj_elev = dem_lat_thal_adj_elev + [ np.array( list( dem_lateral_thalweg_adj.sample( (Point(segment.geometry).coords), indexes=1))).item() ] dem_thal_adj_elev = dem_thal_adj_elev + [ np.array( list( dem_thalwegCond.sample( (Point(segment.geometry).coords), indexes=1))).item() ] headwater_path = headwater_path + [segment.headwater_path] # gpd.GeoDataFrame({**data, "source": "dem_m"}) dem_m_pts = gpd.GeoDataFrame( { 'stream_id': stream_ids, 'source': 'dem_m', 'elevation_m': dem_m_elev, 'headwater_path': headwater_path, 'index_count': index_count, 'geometry': split_points }, crs=path.crs, geometry='geometry') dem_lat_thal_adj_pts = gpd.GeoDataFrame( { 'stream_id': stream_ids, 'source': 'dem_lat_thal_adj', 'elevation_m': dem_lat_thal_adj_elev, 'headwater_path': headwater_path, 'index_count': index_count, 'geometry': split_points }, crs=path.crs, geometry='geometry') dem_thal_adj_pts = gpd.GeoDataFrame( { 'stream_id': stream_ids, 'source': 'thal_adj_dem', 'elevation_m': dem_thal_adj_elev, 'headwater_path': headwater_path, 'index_count': index_count, 'geometry': split_points }, crs=path.crs, geometry='geometry') for raster in [dem_m_pts, dem_lat_thal_adj_pts, dem_thal_adj_pts]: raster = raster.sort_values(by=['index_count']) raster.set_index('index_count', inplace=True, drop=True) raster = raster.reset_index(drop=True) raster.index.names = ['index_count'] raster = raster.reset_index(drop=False) thalweg_points = thalweg_points.append(raster, ignore_index=True) del raster del dem_m_pts, dem_lat_thal_adj_pts, dem_thal_adj_pts del dem_lateral_thalweg_adj, dem_thalwegCond, dem_meters try: # Remove nodata_pts and convert elevation to ft thalweg_points = thalweg_points.loc[thalweg_points.elevation_m > 0.0] thalweg_points.elevation_m = np.round(thalweg_points.elevation_m, 3) thalweg_points['elevation_ft'] = np.round( thalweg_points.elevation_m * 3.28084, 3) # Plot thalweg profile plot_profile(thalweg_points, profile_plots_filename) # Filter final thalweg ajdusted layer thal_adj_points = thalweg_points.loc[thalweg_points.source == 'thal_adj_dem'].copy() # thal_adj_points.to_file(profile_gpkg_filename,driver=getDriver(profile_gpkg_filename)) # Identify significant rises/drops in elevation thal_adj_points['elev_change'] = thal_adj_points.groupby( ['headwater_path', 'source'])['elevation_m'].apply(lambda x: x - x.shift()) elev_changes = thal_adj_points.loc[( thal_adj_points.elev_change <= -lateral_elevation_threshold) | (thal_adj_points.elev_change > 0.0)] if not elev_changes.empty: # elev_changes.to_csv(profile_table_filename,index=False) elev_changes.to_file(profile_gpkg_filename, index=False, driver=getDriver(profile_gpkg_filename)) # Zoom in to plot only areas with steep elevation changes # select_streams = elev_changes.stream_id.to_list() # downstream_segments = [index + 1 for index in select_streams] # upstream_segments = [index - 1 for index in select_streams] # select_streams = list(set(upstream_segments + downstream_segments + select_streams)) # thal_adj_points_select = thal_adj_points.loc[thal_adj_points.stream_id.isin(select_streams)] # plot_profile(thal_adj_points_select, profile_plots_filename_zoom) except: print(f"huc {huc} has {len(thalweg_points)} thalweg points")
vdf = pd.read_csv('Boston-2-vertices_r.csv') edf = pd.read_csv('Boston-2-edges-4am_r.csv') # In[53]: geometry = [] for i, r in edf.iterrows(): s = r['s'] t = r['t'] ps = Point(vdf['lon'][s], vdf['lat'][s]) pt = Point(vdf['lon'][t], vdf['lat'][t]) geometry.append(LineString([ps,pt])) crs = {'proj': 'latlong', 'ellps': 'WGS84', 'datum': 'WGS84', 'no_defs': True} crs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" gdf1 = gpd.GeoDataFrame(edf, geometry=geometry, crs=crs) # In[48]: #%matplotlib inline # fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,8), dpi=150) gdf['color'] = 0.0 ne = 11 gdf.loc[ne,'color'] = 100 gdf.plot(column='color', ax=ax, zorder=1)
def deserialize_line(self, gpbGeometry) -> LineString: points = [ self.coordinate_to_point(coord) for coord in gpbGeometry.coordinates ] return LineString(points)
layout.rename('potential'), average_distance.rename('average_distance')]) if snakemake.wildcards.technology.startswith("offwind"): import geopandas as gpd from shapely.geometry import LineString offshore_shape = gpd.read_file( snakemake.input.offshore_shapes).unary_union underwater_fraction = [] for i in regions.index: row = layoutmatrix[i] centre_of_mass = (cell_coords[row.indices] * (row.data / row.data.sum())[:, np.newaxis]).sum( axis=0) line = LineString([centre_of_mass, regions.loc[i, ['x', 'y']]]) underwater_fraction.append( line.intersection(offshore_shape).length / line.length) ds['underwater_fraction'] = xr.DataArray(underwater_fraction, [buses]) # select only buses with some capacity and minimal capacity factor ds = ds.sel( bus=((ds['profile'].mean('time') > config.get('min_p_max_pu', 0.)) & (ds['p_nom_max'] > config.get('min_p_nom_max', 0.)))) if 'clip_p_max_pu' in config: ds['profile'].values[ ds['profile'].values < config['clip_p_max_pu']] = 0. ds.to_netcdf(snakemake.output.profile)
# parameters N = 2 x = np.arange(N)*length X, Y = np.meshgrid(x, x) ids = np.arange(N**2) pos = list(zip(X.flatten(), Y.flatten())) G.add_nodes_from([add_node(i, x, y) for i, (x, y) in enumerate(pos)]) for i, row in enumerate(ids.reshape(N, N)): for j, node in enumerate(row): if j < N-1: start_node = node end_node = i*N+j+1 edge_attributes["direction"] = EAST edge_attributes["dir_txt"] = "EAST" G.add_edge(start_node, end_node, geometry=LineString( [pos[start_node], pos[end_node]]), **edge_attributes) end_node = node start_node = i*N+j+1 edge_attributes["direction"] = WEST edge_attributes["dir_txt"] = "WEST" G.add_edge(start_node, end_node, geometry=LineString( [pos[start_node], pos[end_node]]), **edge_attributes) if i < N-1: start_node = node end_node = (i+1)*N+j edge_attributes["direction"] = NORTH edge_attributes["dir_txt"] = "NORTH" G.add_edge(start_node, end_node, geometry=LineString( [pos[start_node], pos[end_node]]), **edge_attributes)
def make_linestring(coordinate): from shapely.geometry import LineString line = LineString(coordinate) return line
@pytest.mark.parametrize("lines", LINE_COLLECTION_INIT) def test_line_collection_extend(lines): lc = LineCollection([(3, 3j)]) lc.extend(lines) assert len(lc) == 3 assert np.all(lc[0] == np.array([3, 3j])) assert np.all(lc[1] == np.array([0, 1 + 1j])) assert np.all(lc[2] == np.array([2 + 2j, 3 + 3j, 4 + 4j])) @pytest.mark.parametrize( "line", [ LineString([(4, 3), (5, 0), (10, 10), (0, 5)]), np.array([4 + 3j, 5, 10 + 10j, 5j]), [4 + 3j, 5, 10 + 10j, 5j], ], ) def test_line_collection_append(line): lc = LineCollection() lc.append(line) assert len(lc) == 1 assert np.all(lc[0] == np.array([4 + 3j, 5, 10 + 10j, 5j])) def test_line_collection_bounds(): lc = LineCollection([(-10, 10), (-10j, 10j)]) assert lc.bounds() == (-10, -10, 10, 10)
def create_intersection_stops(stop_1, stop_2, G, dict_distances, dict_geo_data): ''' Detecting intersections between a new connection and existing connections. For each intersection, the closest existing stop is computed. Parameters ---------- stop_1 : string name of a stop to be connected. stop_2 : string name of the other stop to be connected. G : Graph graph where intersections between connections need to be detected. dict_distances : dictionary dictionary where the key is a stop and the value is a dictionary containing the distances between that stop and all other stops. dict_geo_data : dictionary dictionary where the key is a stop and the value is a dictionary containing its location data. Returns ------- list list of the stops where the new connection will intersect. dict_existing_connections : dictionary dictionary where the key is a stop and the value is a list of all the stop it connecs to through a walking edge. ''' # list that will contain the list of stops intersecting with the edge # between stop_1 and stop_2 list_intersections = [] # dictionary containing the stops that are connected by a walking edge # with the stops present in list_intersections # key = stop in list_intersections, value = list of connected stops dict_existing_connections = {} # creating a line object connecting the two new stops we want to make new_connection = (stop_1, stop_2) new_stop_1_location = (dict_geo_data[new_connection[0]]['lon'], dict_geo_data[new_connection[0]]['lat']) new_stop_2_location = (dict_geo_data[new_connection[1]]['lon'], dict_geo_data[new_connection[1]]['lat']) coords_new = [new_stop_1_location, new_stop_2_location] line_new = LineString(coords_new) list_intersections.append(stop_1) list_intersections.append(stop_2) # adding the connections of stop_1 and stop_2 dict_existing_connections[stop_1] = [ connection[1] for stop in list_intersections for connection in list(G.edges(stop_1, data=True)) if connection[2]['mode'] == 'walk' ] dict_existing_connections[stop_2] = [ connection[1] for stop in list_intersections for connection in list(G.edges(stop_2, data=True)) if connection[2]['mode'] == 'walk' ] # list of connections to test for intersection list_connections = [ edge for edge in list(G.edges(data=True)) if edge[2]['mode'] != 'walk' ] for existing_connection in list_connections: # creating a line object between two existing stops old_stop_1 = (dict_geo_data[existing_connection[0]]['lon'], dict_geo_data[existing_connection[0]]['lat']) old_stop_2 = (dict_geo_data[existing_connection[1]]['lon'], dict_geo_data[existing_connection[1]]['lat']) coords_old = [old_stop_1, old_stop_2] line_old = LineString(coords_old) if ((line_old.intersects(line_new)) and (len(list(set(coords_old) & set(coords_new))) == 0)): # if the two lines intersect, a connection between the new line # and the existing line is created intersection_coord = line_old.intersection(line_new) # computing which stop of the intersecting edge is the closest # to the intersection if (intersection_coord.distance(Point(old_stop_1)) < intersection_coord.distance(Point(old_stop_2))): intersection_stop = existing_connection[0] else: intersection_stop = existing_connection[1] if ((intersection_stop not in list_intersections) and intersection_stop not in [ stop for connection in [*dict_existing_connections.values()] for stop in connection ]): # useful not to create different transit connections # between stops that are already connected # we can now add the intersection stop to the list # and add the stops it is connected to through a walking edge list_intersections.append(intersection_stop) dict_existing_connections[intersection_stop] =\ [connection[1] for connection in list(G.edges(intersection_stop, data=True)) if connection[2]['mode'] == 'walk'] # now that all intersection stops have been found # the distances between stop_1 and all the stops are computed # so that the correct ordering of the intersection stops is found list_distances = [ (stop, dict_distances[stop][stop_1]) if stop != stop_1 else (stop, 0) for stop in list_intersections ] list_distances = sorted(list_distances, key=lambda x: x[1]) return [stop[0] for stop in list_distances], dict_existing_connections
def find_optimal_cut(P, v): """ Find optimal cut """ pois = [] min_altitude, theta = alt.get_min_altitude(P) s = find_cut_space(P, v) # print("Cut space: %s"%(s,)) min_altitude_idx = None # First, find edges on cut space that are collinear with reflex vertex collinear_dict = form_collinear_dictionary(s, v) # print collinear_dict # for i in range(1, len(s)): # si = [s[i-1], s[i]] for si in s: # Process each edge si, have to be cw lr_si = LinearRing([v[1]] + si) if lr_si.is_ccw: #print lr_si #print lr_si.is_ccw si = [si[1]] + [si[0]] #print si cut_point = si[0] #print P, v, cut_point p_l, p_r = perform_cut(P, [v[1], cut_point]) if p_l is None and p_r is None: continue if not LineString(p_l).is_simple: continue if not LineString(p_r).is_simple: continue dirs_left = directions.get_directions_set([p_l, []]) dirs_right = directions.get_directions_set([p_r, []]) #print dirs_left #print list(degrees(dir) for dir in dirs_left) #print get_altitude([p_l,[]], 3.5598169831690223) #print get_altitude([p_r,[]], 0) # Look for all transition points for dir1 in dirs_left: for dir2 in dirs_right: tp = find_best_transition_point(si, v[1], dir1, dir2) # Here check if tp is collinear with v # If so and invisible, replace with visible collinear point if tp in collinear_dict.keys(): pois.append((collinear_dict[tp], dir1, dir2)) else: pois.append((tp, dir1, dir2)) #print("R: %s Points of interest: %s"%(v[1], pois,)) # Evaluate all transition points for case in pois: p_l, p_r = perform_cut(P, [v[1], case[0]]) if p_l is None and p_r is None: continue if not LineString(p_l).is_simple: continue if not LineString(p_r).is_simple: continue a_l = alt.get_altitude([p_l, []], case[1]) a_r = alt.get_altitude([p_r, []], case[2]) #from math import degrees #print("Cut from: %s to %s"%(v[1], case[0])) #print("Alt_l: %2f at %2f, Alt_r: %2f at %2f"%(a_l, degrees(case[1]), a_r, degrees(case[2]))) if round(a_l + a_r, 5) < round(min_altitude, 5): min_altitude = a_l + a_r min_altitude_idx = case #print min_altitude, min_altitude_idx[0], degrees(min_altitude_idx[1]), degrees(min_altitude_idx[2]) # print v[1] # print min_altitude_idx return min_altitude_idx
def chainage_on_line(point: Point, line: LineString) -> float: # Find chainage of line closest to point # point: Shapely Point # lines: Shapely Polylines # return return line.project(point)