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
示例#2
0
    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,
            }
        )
示例#3
0
    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))
示例#4
0
文件: pseudo.py 项目: gturco/pseudo
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
示例#5
0
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
示例#7
0
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
示例#8
0
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)
     ])
示例#10
0
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
示例#11
0
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')
示例#12
0
    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
示例#14
0
    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))
示例#15
0
 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]
示例#17
0
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)
示例#18
0
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
示例#19
0
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)
示例#20
0
文件: matcher.py 项目: renj/TrajMap
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
示例#21
0
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}}
            )
示例#22
0
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
示例#23
0
 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)
示例#24
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
示例#25
0
    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)
示例#26
0
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
示例#27
0
 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
示例#29
0
    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
示例#30
0
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
示例#31
0
 def __init__(self, start, end, figure=None):
     self.start, self.end = start, end
     self.line = LineString([start, end])
     self.figure = figure
示例#32
0
 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))
示例#33
0
 def crosses(self, item):
     item = LineString(item)
     return any(item.crosses(e.line) for e in self.inner_edges)
示例#34
0
 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]))
示例#35
0
    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"]}
        )
示例#36
0
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)]
示例#37
0
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)
示例#39
0
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)

示例#40
0
 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
示例#41
0
    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)
示例#42
0
    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))
示例#43
0
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
示例#44
0
 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()
示例#46
0
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
示例#47
0
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')
示例#48
0
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
示例#49
0
        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
示例#51
0
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")
示例#52
0

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)
示例#54
0
                   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)
示例#56
0
def make_linestring(coordinate):
    from shapely.geometry import LineString
    line = LineString(coordinate)
    return line
示例#57
0

@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
示例#59
0
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)