def bounce(self, shape_ball, shape): strike = LineString([self.ball_origin, shape_ball.center]) # going down if self.ball.speed[1] > 0: top = LineString([shape.topleft, shape.topright]) if strike.crosses(top): self.ball.onYBounce() return True # going up else: bottom = LineString([shape.bottomleft, shape.bottomright]) if strike.crosses(bottom): self.ball.onYBounce() return True # going right if self.ball.speed[0] > 0: left = LineString([shape.topleft, shape.bottomleft]) if strike.crosses(left): self.ball.onXBounce() return True # going left else: right = LineString([shape.topright, shape.bottomright]) if strike.crosses(right): self.ball.onXBounce() return True return False
def can_connect_fast(polygons, tree_poly, p1, p2): """ Faster implementation of can_connect() method using random sampling of points on the line between p1 and p2 and KDTree to query for polygons that are close to the points Args: polygons (tuple): containing (polygon, height) for all obstacles tree_poly (KDTree): indexed using ploygon vertices p1 (tuple): containing north, east coordinate of first point p2 (tuple): containing north, east coordinate of first point Returns: (bool): True of p1 and p2 can be connected. False otherwise. """ # Find closest poly for p1 and p2 and check if line # intersects with one of them l = LineString([p1, p2]) # Find closeset polygon to the points idx = tree_poly.query([np.array(p1)], k=1, return_distance=False)[0] poly1 = polygons[idx[0]][0] if l.crosses(poly1): return False # Sample points on the line # for i in [0.25, 0.5, 0.75]: for i in np.arange(0.1, 0.9, 0.1): p = l.interpolate(i, normalized=True) # print(p) idx = tree_poly.query([np.array(p)], k=1, return_distance=False)[0] poly2 = polygons[idx[0]][0] # If line crosses the any polygon, we cannot connect if l.crosses(poly2): return False return True
def reachable_vertices_by_state(current_state, goal_state, closed_set): reachable_vertices = [] # print("Check reachable nodes from the current node: " + str(current_state)) for polygon in polygons: for vertex in polygon.exterior.coords: # if we have it, move on if vertex in reachable_vertices: continue # ignore closed nodes if vertex in closed_set: continue # let's not test ourselves if current_state == vertex: test_line_valid = False # print("Don't need to test the current state...") continue else: test_line_valid = True test_line = LineString((current_state, vertex)) # print("Testing if " + str(vertex) + " is reachable...") obstacle_names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] i = 0 for obstacle in polygons: if test_line.crosses(obstacle): # print("Obstacle '" + obstacle_names[i] + "' is in the way of point " + str(vertex)) test_line_valid = False break if test_line.within(obstacle): # print("Skip non-adjacent vertices on the same obstacle '" + obstacle_names[i] + "' :" + str(vertex)) test_line_valid = False break i += 1 if test_line_valid: # print(str(test_line) + " is reachable!") reachable_vertices.append(vertex) # Test for goal state line_to_goal = LineString((current_state, goal_state)) line_to_goal_blocked = False for obstacle in polygons: if line_to_goal.crosses(obstacle) or line_to_goal.within(obstacle): line_to_goal_blocked = True break if not line_to_goal_blocked: reachable_vertices.append(goal_state) return reachable_vertices
def can_connect(self, p1, p2): line = LineString([p1, p2]) for p in self.polygons: if line.crosses(p[0]) and p[1] >= min(p1[2], p2[2]): return False else: return True
def find_valid_edges(vertexes, edges, env, polygons): valid_edges = [] for i, p1 in enumerate(vertexes): print i for p2 in [x for x in vertexes if not x == p1]: add = True line2 = LineString([p1, p2]) if env.crosses(line2): continue xx, yy = line2.xy # Midpoint will lie within a shape if the line is composed of two vertices of the polygon m = Point(sum(xx)/2., sum(yy)/2.) if [x for x in polygons if m.within(x)]: continue # skip this edge if it is within a polygon for edge in edges: line1 = LineString(edge) if add and not line1 == line2 and line1.crosses(line2): add = False break if add: valid_edges.append([p1, p2]) return valid_edges
def isAllVisible(p: Point, poly: Polygon): vtx = list(poly.exterior.coords) for p1 in range(len(vtx)): line_center = LineString([p, vtx[p1]]) if line_center.crosses(poly): return False return True
def get_children(parent, constraint, polys=[], vlist=[]): # get kids of nodeState # if parent.children is empty if not parent.children: # cycle through vertex list(vList) for x in vlist: # create line from parent to vertex testLine = LineString([(parent.location.x, parent.location.y), (x.x, x.y)]) notChild = False # if x is parent location if x.x == parent.location.x and x.y == parent.location.y or testLine.length > constraint: notChild = True else: # cycle through polygon list(poly) for y in polys: # if testline crosses a polygon if testLine.crosses(y): notChild = True # if testline is within a polygon elif testLine.within(y): notChild = True # if notchild is false if not notChild: # new node and append to parent new = nodeState(x, parent) parent.children.append(new)
def center_permanency(row, polygon=center_polygon): """ Computes the percentage of a trajectory's stay in Atlanta's center. Having an entry-to-exit trajectory with length n, its center permanency represents the percentage of n that happens inside Atlanta's center polygon, in a [0,1] interval. Trajectories starting and ending within the center will then have permanency equal to 1, as those that start and end out of the center have it equal to 0. Parameters ---------- row : pandas.Series Row onto which the center permanency will be based. Returns ------- float The entry-to-exit trajectory center permanency as a percentage. """ if any(np.isnan(row[col]) for col in ['x_exit', 'y_exit']): return np.nan line = LineString([(row['x_entry'], row['y_entry']), (row['x_exit'], row['y_exit'])]) crossed = line.crosses(polygon) if not line.intersects(polygon): return 0 if line.length == 0: # Avoids divisions by 0 in 'point' trajectories return 1 return line.intersection(polygon).length / line.length
def SpatialToplogy (Spatial_A,Spatial_B): if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Point': Point_0=Point(Spatial_A[0],Spatial_A[1]) Point_1=Point(Spatial_B[0],Spatial_B[1]) #Point to point relationships if Point_0.equals(Point_1): return 'Point1 equals Point2' if Point_0.within(Point_1.buffer(2)): return 'Point1 lies within a buffer of 2 m from Point2' if Point_0.overlaps(Point_1): return 'Point1 overlaps Point2' #if Point_0.disjoint(Point_1): return 'Point1 disjoint Point2' #Point to line relationships if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Line': Point_0=Point(Spatial_A[0],Spatial_A[1]) Line_0=LineString([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[3])]) if Point_0.touches(Line_0):return 'Point1 touches Line1' if Point_0.within(Line_0.buffer(2)):return 'Point1 lies within a buffer of 2 m from L1' #Point to polygon relationships if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Polygon': Point_0=Point(Spatial_A[0],Spatial_A[1]) Polygon_0=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Point_0.touches(Polygon_0):return 'Point1 touches Polygon1' if Point_0.within(Polygon_0):return'Point1 lies within Polygon1' if Point_0.overlaps(Polygon_0):return 'Point1 lies overlaps Polygon1' #Line to line relationships if Spatial_A[4]=='Line' and Spatial_B[4]=='Line': Line_0=LineString([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[3])]) Line_1=LineString([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[3])]) if Line_0.equals(Line_1):return 'Line0 equals Line1' if Line_0.touches(Line_1):return 'Line0 touches Line1' if Line_0.crosses(Line_1):return 'Line0 crosses Line1' if Line_0.within(Line_1.buffer(2)):return 'Line0 lies within a buffer of 2 m Line1' if Line_0.overlaps(Line_1):return 'Line0 overlaps Line1' #Line to polygon relationships if Spatial_A[4]=='Line' and Spatial_B[4]=='Polygon': Line_0=LineString([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[3])]) Polygon_0=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Line_0.touches(Polygon_0):return 'Line0 touches Polygon1' if Line_0.crosses(Polygon_0):return 'Line0 crosses Polygon1' if Line_0.within(Polygon_0):return 'Line0 lies within Polygon1' #Polygon to Polygon relationships if Spatial_A[4]=='Polygon' and Spatial_B[4]=='Polygon': Polygon_0=Polygon([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[1]),(Spatial_A[2],Spatial_A[3]),(Spatial_A[0],Spatial_A[3])]) Polygon_1=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Polygon_0.touches(Polygon_1):return 'Polygon touches Polygon1' if Polygon_0.equals(Polygon_1):return 'Polygon0 equals Polygon1' if Polygon_0.within(Polygon_1):return 'Polygon lies within Polygon1' if Polygon_0.within(Polygon_1.buffer(2)):return 'Polygon lies within a buffer of 2m Polygon1'
def __call__(self): results = [] Line = LineString(self.in_path) for obs in self.in_obs: if Line.crosses(obs): results.append(self.in_path) break return results
def crosses(shape, coord1, coord2): polygon = Polygon(shape) line = LineString([coord1, coord2]) if line.intersects(polygon): if line.touches(polygon): return False elif line.crosses(polygon): return True
def crossed_city(row): if any(np.isnan(row[col]) for col in ['x_exit', 'y_exit']): return np.nan line = LineString([(row['x_entry'], row['y_entry']), (row['x_exit'], row['y_exit'])]) crossed = 1 if line.crosses(center_polygon) is True else 0 return crossed
def _crosses_antimeridian(region: Polygon) -> bool: """ Determine if the given region crosses the Antimeridian line, by converting the given Polygon from -180;180 to 0;360 and checking if the antimeridian line crosses it. This only works with Polygons without holes :param region: Polygon to test """ # Retrieving the points of the Polygon are a bit troublesome, parsing WKT # is more straightforward and probably faster new_wkt = 'POLYGON ((' # TODO (forman): @JanisGailis this is probably the most inefficient antimeridian-crossing-test I've ever seen :D # What is the problem in using the exterior longitude coordinates? # Please note: # - WKT parsing and formatting is actually NEVER faster than direct coordinate access (C-impl.!) # - The polygon's interior can be neglected, only the exterior is required for the test # - Area computations as used here are probably expensive. # - An accurate and really fast test takes the orientation into account (polygon.is_ccw) # and detects intersections of each segement with the antimeridian line. # [10:-2] gets rid of POLYGON (( and )) for point in dumps(region)[10:-2].split(','): point = point.strip() lon, lat = point.split(' ') lon = float(lon) if -180 <= lon < 0: lon += 360 new_wkt += '{} {}, '.format(lon, lat) new_wkt = new_wkt[:-2] + '))' converted = loads(new_wkt) # There's a problem at this point. Any polygon crossed by the zeroth # meridian can in principle convert to an inverted polygon that is crossed # by the antimeridian. if not converted.is_valid: # The polygon 'became' invalid upon conversion => probably the original # polygon is what we want return False test_line = LineString([(180, -90), (180, 90)]) if test_line.crosses(converted): # The converted polygon seems to be valid and crossed by the # antimeridian. At this point there's no 'perfect' way how to tell if # we wanted the converted polygon or the original one. # A simple heuristic is to check for size. The smaller one is quite # likely the desired one if converted.area < region.area: return True else: return False
def can_connect(p1, p2, polygons): """ Given two points p1 and p2, checks whether a line between them does not cross a polygon """ line = LineString([p1, p2]) connect = True for (p, h) in polygons: if line.crosses(p) and min(p1[2], p2[2]) <= h: connect = False break return connect
def update_links(self, node_list, obstruction_list): for node in node_list: if not self.co_ords == node.co_ords: line_attempt = LineString([self.co_ords, node.co_ords]) success = True for obstruction in obstruction_list: if line_attempt.crosses(obstruction.polygon): success = False break if success == True: self.links.append(node.id)
def cell_decomp(self, obstruction_list): """Performs trapezoidal cell decomposition for individual block""" self.block_nodes = [] self.obstrucion_list = obstruction_list # self.bbox = box(self.polygon.bounds) for i in self.polygon.exterior.coords: new_line = LineString([i, (i[0], 0)]) if new_line.crosses(self.polygon): new_line = LineString(i, (i.x, 300)) for j in obstruction_list: if new_line.crosses(j.polygon): new_line = LineString( [i, (new_line.intersection(j.polygon.boundary))[0]]) node_coords = new_line.interpolate(0.5, normalized=True).coords[:][0] # print ("node created at " + str(node_coords)) self.block_nodes.append(node_coords) # print ("block nodes created:- " + str(self.block_nodes)) return self.block_nodes
def _crosses_antimeridian(region: Polygon) -> bool: """ Determine if the given region crosses the Antimeridian line, by converting the given Polygon from -180;180 to 0;360 and checking if the antimeridian line crosses it. This only works with Polygons without holes :param region: Polygon to test """ # Convert region to only have positive longitudes. # This way we can perform a simple antimeridian check old_exterior = region.exterior.coords new_exterior = [] for point in old_exterior: lon, lat = point[0], point[1] if -180. <= lon < 0.: lon += 360. new_exterior.append((lon, lat)) converted_region = Polygon(new_exterior) # There's a problem at this point. Any polygon crossed by the zero-th # meridian can in principle convert to an inverted polygon that is crossed # by the antimeridian. if not converted_region.is_valid: # The polygon 'became' invalid upon conversion => probably the original # polygon is what we want # noinspection PyBroadException try: # First try cleaning up geometry that is invalid converted_region = converted_region.buffer(0) except BaseException: pass if not converted_region.is_valid: return False test_line = LineString([(180, -90), (180, 90)]) if test_line.crosses(converted_region): # The converted polygon seems to be valid and crossed by the # antimeridian. At this point there's no 'perfect' way how to tell if # we wanted the converted polygon or the original one. # A simple heuristic is to check for size. The smaller one is quite # likely the desired one if converted_region.area < region.area: return True else: return False else: return False
def LOS(n1, n2, obstacles): p1 = (n1.x, n1.y) p2 = (n2.x, n2.y) line = LineString([p1, p2]) obstructed = False for obstacle in obstacles: shape = obstacle['polygon'] if line.crosses(shape) or shape.contains(line): obstructed = True break return not obstructed
def can_connect(self, p1, p2): #line = LineString(p1, p2) line = LineString([p1, p2]) h = self.TARGET_ALTITUDE if len(p1) == 3: h = min(p1[2], p2[2]) for p in self.polygons: if line.crosses(p[0]) and p[1] >= h: return False else: return True
class Edge: def __init__(self, start, end, figure=None): self.start, self.end = start, end self.line = LineString([start, end]) self.figure = figure def intersects_with(self, other_line: tuple): if self.figure and all( p in self.figure for p in other_line) and self.figure.crosses(other_line): return True return self.line.crosses(LineString(other_line))
def checkLineIntersection(Ax1y1: list, Ax2y2: list, Bx1y1: list, Bx2y2: list, canTouch: bool) -> list: line1 = LineString([Ax1y1, Ax2y2]) line2 = LineString([Bx1y1, Bx2y2]) intersect = line1.intersection(line2) if intersect.is_empty or not line1.crosses(line2): if not canTouch: return False, [0, 0] try: return True, [intersect.x, intersect.y] except: return False, [0, 0]
def _crosses_antimeridian(region: PolygonLike.TYPE) -> bool: """ Determine if the given region crosses the Antimeridian line, by converting the given Polygon from -180;180 to 0;360 and checking if the antimeridian line crosses it. This only works with Polygons without holes :param region: PolygonLike to test """ region = PolygonLike.convert(region) # Retrieving the points of the Polygon are a bit troublesome, parsing WKT # is more straightforward and probably faster new_wkt = 'POLYGON ((' # [10:-2] gets rid of POLYGON (( and )) for point in dumps(region)[10:-2].split(','): point = point.strip() lon, lat = point.split(' ') lon = float(lon) if -180 <= lon < 0: lon += 360 new_wkt += '{} {}, '.format(lon, lat) new_wkt = new_wkt[:-2] + '))' converted = loads(new_wkt) # There's a problem at this point. Any polygon crossed by the zeroth # meridian can in principle convert to an inverted polygon that is crossed # by the antimeridian. if not converted.is_valid: # The polygon 'became' invalid upon conversion => probably the original # polygon is what we want return False test_line = LineString([(180, -90), (180, 90)]) if test_line.crosses(converted): # The converted polygon seems to be valid and crossed by the # antimeridian. At this point there's no 'perfect' way how to tell if # we wanted the converted polygon or the original one. # A simple heuristic is to check for size. The smaller one is quite # likely the desired one if converted.area < region.area: return True else: return False
def check_crossings_in_surrounding(self, surrounding_boundary_edges, old_coords, new_coords, third_coords): crossing_found = False for edge in surrounding_boundary_edges: segment1 = LineString([self.vertices[edge[0]], self.vertices[edge[1]]]) # We have to check all crossings between the edge and the triangle [old, new, third] # first check segment2 = LineString([old_coords, new_coords]) if segment1.crosses(segment2): crossing_found = True # print("Break - checkCrossings_in_surrounding 1") break # second check segment2 = LineString([old_coords, third_coords]) if segment1.crosses(segment2): crossing_found = True # print("Break - checkCrossings_in_surrounding 2") break # third check segment2 = LineString([new_coords, third_coords]) if segment1.crosses(segment2): crossing_found = True # print("Break - checkCrossings_in_surrounding 3") break return crossing_found
def calc_ma_crossover_points( array1: pd.Series, array2: pd.Series) -> Iterable[tuple]: # array indexes are returned """ Calculate the points (index, YYYY-mm-dd, price) where array1 and array2 cross over and return them. Typically they represent MA20 and MA200 lines, but any two poly lines will do. """ assert len(array1) == len(array2) ls1 = [] ls2 = [] for i in range(len(array1)): v1 = array1[i] v2 = array2[i] if np.isnan(v1) or np.isnan( v2 ): # TODO FIXME: gaps can create false overlaps due to "straight line" intersections in error... GIGO... continue ls1.append((i, v1)) ls2.append((i, v2)) result = None ls1 = LineString(ls1) ls2 = LineString(ls2) if ls1.crosses(ls2): # symettry: implies ls2.crosses(ls1) result = ls1.intersection(ls2) if result is None or result.is_empty: return [] elif isinstance(result, Point): nearest_idx = int(result.x) return [(nearest_idx, array1[nearest_idx], result.y)] else: # assume multiple points ie. MultiPoint ret = [] # print(result) for hit in list(result): if isinstance(hit, Point): nearest_idx = int(hit.x) intersect_price = hit.y elif isinstance(hit, LineString): # if a hit exists over multiple consecutive days, we just report the start coords = list(hit.coords) nearest_idx, intersect_price = coords[0] else: assert False # fail for obscure corner cases # print(array1) ret.append( (nearest_idx, array1.index[nearest_idx], intersect_price)) return ret
def can_connect(node1, node2, polygons): # 2) write a method "can_connect()" that: # casts two points as a shapely LineString() object # tests for collision with a shapely Polygon() object # returns True if connection is possible, False otherwise possible = False n1 = np.array(node1) n2 = np.array(node2) line = LineString([n1[:2], n2[:2]]) for poly in polygons: possible = False if not line.crosses(poly[0]): # and poly[1] >= min(n1[2], n2[2]): possible = True elif possible == False: break return possible
def rec_path(self, A, B, d, sens=0): # print("d : ", d) line = LineString((A, B)) # if d>5: # return (A, B), d if not self.terrain.contains(line): return None, 0 for obs in self.obstacles: if line.crosses(obs): coords = (obs.union(line)).convex_hull.exterior.coords i = list(coords).index(A) if sens != 0: #print("AHHHH ! : ", (i+sens)%len(list(coords))) C = coords[(i + sens) % len(list(coords))] # print("C1, C2 : ", C1, C2) pts, d0 = self.rec_path(C, B, d, sens=sens) if pts == None: return None, 0 d += d0 else: C1, C2 = coords[i + 1], coords[(i - 2) % len(list(coords))] # print("C1, C2 : ", C1, C2) pts1, d1 = self.rec_path(C1, B, d, sens=1) pts2, d2 = self.rec_path(C2, B, d, sens=-2) if d1 > d2 or pts1 == None: C = C2 pts = pts2 d += d2 if pts == None: return None, 0 else: C = C1 pts = pts1 d += d1 d += cdist( np.array(A).reshape(1, -1), np.array(C).reshape(1, -1)) pts.insert(0, A) return pts, d d += cdist(np.array(A).reshape(1, -1), np.array(B).reshape(1, -1)) return [A, B], d
def RRT(start,goal,obstacle_list): ''' The search space will be a rectangular space defined by (0,0),(0,10),(10,0),(10,10) ''' goalr = [(goal[0]-0.3,goal[1]-0.3),(goal[0]+0.3,goal[1]-0.3), (goal[0]+0.3,goal[1]+0.3), (goal[0]-0.3,goal[1]+0.3)] Qgoal = dgoal(goalr) obstacles = obst(obstacle_list) cnt = 0 graph = Tree(Point(start[0],start[1])) while cnt < 5000: x = random.random() * 10 y = random.random() * 10 p = Point(x,y) if IsInObstacle(obstacles, p): continue n = nearestNode(p, graph, 10**6) line = LineString([n[1].data,p]) if n[0] >= 1: p = line.interpolate(1) x = p.x y = p.y line = LineString([n[1].data,p]) if line.crosses(obstacles): continue last = chain(n[1],p) if IsInObstacle(Qgoal,p): print("Found it!") return graph.tb(last),Qgoal cnt += 1 return graph.tb(last),Qgoal
def find_local_goal(self, path: Path, i_start=0): crossing_lines = [] for i in range(i_start, len(path.nodes) - 1): path_segment = LineString(path.nodes[i:i + 2]) if path_segment.crosses(self.packet_poly.exterior): crossing_lines.append(path_segment) if len(crossing_lines) < 1: logging.warning("Cannot find local goal") return # The last crossing on the path is the closest to the final goal last_crossing = crossing_lines[-1] intersections = last_crossing.intersection(self.packet_poly.exterior) # TODO - Handle multiple crossings on a line local_goal = intersections.coords[0] return local_goal
def check_course_geofence (self, x_utm_start, y_utm_start, az = None, dist = None, x_utm_end = None, y_utm_end = None): ''' method to check a prospective course to see how it stacks up against the geofence. If the start is outside the geofence, this returns true if the course intersects into the geofence. If the start is inside the geofence, this returns true if we don't intersect the geofence, and false if we do cross the geofence. x_utm_start = the starting point of the line y_utm_start = the starting point of the line az = the compass azimuth of where the line is going dist = the distance of the line x_utm_end = optionally supplied x_utm location for course line y_utm_end = optionally supplied x_utm location for course line returns true (yes, this course is fine), or false (not so good) ''' # calc the end points with az and dist if end points are unsupplied if not az is None and not dist is None: x_utm_end = x_utm_start + (dist * sin (az * pi / 180.0)) y_utm_end = y_utm_start + (dist * cos (az * pi / 180.0)) target_line = LineString ([(x_utm_start, y_utm_start), (x_utm_end, y_utm_end)]) # check to see if the course crosses the edge of the geofence crossing_geofence = target_line.crosses (self.geofence) # now, see if we are going into the geofence, or out of the geofence start_in_geofence = self.check_geofence (x_utm_start, y_utm_start) # check the combinations if start_in_geofence: if crossing_geofence: good_course = False # looks bad, crossing geofence else: good_course = True # looks good, not crossing geofence else: if crossing_geofence: good_course = True # looks good, we are going back into the geofence else: good_course = False # looks bad, not going back into the geofence return (good_course)
def createConvexPath(pair, case): #print pair odPointsList = ((pair[0].x, pair[0].y), (pair[1].x, pair[1].y)) st_line = LineString(odPointsList) labeledObstaclePoly = [] totalConvexPathList = {} if case == 'ff': if st_line.length > fd_fullPayload * 5280: return 0, 0, None elif case == "fd": if st_line.length > fd_delivery * 5280: return 0, 0, None dealtArcList = {} totalConvexPathList[odPointsList] = LineString(odPointsList) LineString terminate = 0 idx_loop1 = 0 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 no_obs = False while terminate == 0: t1s = time.time() idx_loop1 += 1 t6s = time.time() totalGrpah = 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]]) crossingDict = defaultdict(list) for line in spatial_filter: Line = LineString(line) for obs in 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 no_obs = True 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 = createConvexhull(obs, tLine) splitBoundary(totalConvexPathList, convexHull) convexHull = createConvexhull(obs, odPointsList) splitBoundary(totalConvexPathList, convexHull) convexHull2 = 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 = 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 = createConvexhull(obs2, [pt]) 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: t7e = time.time() time_loop1_crossingDict += t7e - t7s #new lines labeled_multyPoly = MultiPolygon([x for x in labeledObstaclePoly]) convexHull = createConvexhull(labeled_multyPoly, odPointsList) 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 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: t4s = time.time() for tLine in crossingDict.keys(): dealtArcList[tLine] = crossingDict[tLine] containingObs = [] for obs in crossingDict[tLine]: chk_contain = 0 convexHull2 = 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 = createConvexhull(obs, tLine) 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 = 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 = createConvexhull( obs2, [pt]) 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 #end of while2 for line in impededPathList: if not totalConvexPathList.has_key(line): totalConvexPathList[line] = impededPathList[line] #totalConvexPathList.extend(impededPathList) #no obstruction if no_obs == True: return 1, st_line.length, st_line totalGraph = 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(path + "totalpath" + 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(path + "ESP_" + version_name + "%d" % pair[1]) targetPysal = pysal.IOHandlers.pyShpIO.shp_file(path + "ESP_" + version_name + "%d" % pair[1]) targetShp = generateGeometry(targetPysal) total_length = 0 for line in targetShp: total_length += line.length if case == "ff": if total_length <= fd_fullPayload: return 1, total_length, esp else: return 0, 0 elif case == 'fd': if total_length <= fd_delivery: return 1, total_length, None else: return 0, 0
geo_axes.set_extent([-120, -115, 30, 35], ccrs.PlateCarree()) geo_axes.plot(-117.1625, 32.715, "bo", markersize=7, transform=ccrs.Geodetic()) geo_axes.plot(-118.1625, 33.715, "bo", markersize=7, transform=ccrs.Geodetic()) geo_axes.text(-117, 33, "San Diego", transform=ccrs.Geodetic()) geo_axes.set_xmargin(0.05) geo_axes.set_ymargin(0.10) # ridge_vertices is the "voronoi lines". for vert1, vert2 in vor.ridge_vertices: # each one is a pair [vert1, vert2] if vert1 < 0 or vert2 < 0: continue point1 = np.array(vor.vertices[vert1]) point2 = np.array(vor.vertices[vert2]) line1 = LineString([point1, point2]) if line1.crosses(bounds): line_within = line1.intersection(bounds) map.add_children(folium.PolyLine(locations=line_within.coords)) # |bounds| is a polygon so the intersection is the part that is # within the polygon. geometries.append(line_within) elif not line1.within(bounds): continue # don't draw this, it's outside SF else: map.add_children(folium.PolyLine(locations=[point1, point2])) geometries.append(line1) map.save(args.map_output_file) geo_axes.add_geometries(geometries, ccrs.PlateCarree()) plt.show()
def fld_demo4(image, sheet_dict, split_x, name, save_path): image_ = image.copy() img = Image.fromarray(image) t = time.time() img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # ret, binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) fld = cv2.ximgproc.createFastLineDetector() dlines = fld.detect(img_gray) lines = [line[0] for line in dlines.tolist()] lines_arr = np.array(lines) width_ = lines_arr[:, 2] - lines_arr[:, 0] height_ = lines_arr[:, 3] - lines_arr[:, 1] lines_index1 = np.where(width_ > 50)[0] lines_index2 = np.where(height_ > 50)[0] lines_index = np.hstack([lines_index1, lines_index2]) new_lines = [lines[ele] for ele in lines_index] new_lines = clean_repeat_lines(new_lines) lines_tmp = filter_long_distance_lines(new_lines, sheet_dict) # lines_without_mark = filter_line_in_mark(new_lines, sheet_dict) # 检验滤线这一步骤有没有问题 for dline in lines_tmp: x0 = int(round(dline[0])) y0 = int(round(dline[1])) x1 = int(round(dline[2])) y1 = int(round(dline[3])) cv2.line(image, (x0, y0), (x1, y1), (0, 255, 0), 1, cv2.LINE_AA) text = str([x0, y0, x1, y1]) # cv2.putText(image, text, (x1, y1), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 1) # write_single_img(image, os.path.join(save_path, name + '_raw_lines' + '.jpg')) # get roi polygon 适当放大一点区域,使的线能包含在面里 roi_box_polygon = [] for index, region_box in enumerate(sheet_dict): if region_box['class_name'] in class_above_edge: coordinates = region_box['bounding_box'] xmin = coordinates['xmin'] - 5 ymin = coordinates['ymin'] - 5 xmax = coordinates['xmax'] + 5 ymax = coordinates['ymax'] + 5 box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]) roi_box_polygon.append(box_polygon) # cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255), 1) # cv2.imwrite(r'E:\111_4_26_test_img\aa\save\enlarge_box.jpg', image) # print(roi_box_polygon) # 对line进行分横向纵向 landscape_list_tmp = [] # 横向 longitudinal_list_tmp = [] # 纵向 for ele in lines_tmp: if int(ele[2]) - int(ele[0]) < 10: # 纵向 longitudinal_list_tmp.append(ele) elif int(ele[3]) - int(ele[1]) < 10: # 横向 landscape_list_tmp.append(ele) # print(longitudinal_list_tmp) points_all_list = [] points_list = [] for index, box_polygon in enumerate(roi_box_polygon): extend_line_lan = LineString() extend_line_lon = LineString() # points_list = [] for line1 in landscape_list_tmp: for line2 in longitudinal_list_tmp: # 这部分对原先出来的线进行增大 raw_line_lan = LineString([(line1[0], line1[1]), (line1[2], line1[3])]) # 横向增加5个像素 line_start_lan, line_end_lan = raw_line_lan.bounds[ 0], raw_line_lan.bounds[1] raw_line_lon = LineString([(line2[0], line2[1]), (line2[2], line2[3])]) # 纵向的增加5个像素 line_start_lon, line_end_lon = raw_line_lon.bounds[ 0], raw_line_lon.bounds[1] # decision1 = [raw_line_lan.within(box_polygon), raw_line_lan.contains(box_polygon), raw_line_lan.overlaps(box_polygon)] # decision2 = [raw_line_lon.within(box_polygon), raw_line_lon.contains(box_polygon), raw_line_lon.overlaps(box_polygon)] decision1 = [ raw_line_lan.within(box_polygon), raw_line_lan.contains(box_polygon) ] decision2 = [ raw_line_lon.within(box_polygon), raw_line_lon.contains(box_polygon) ] if True in decision1 and True in decision2: # 这里需要考虑延长左边还是右边 bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax = box_polygon.bounds[0], box_polygon.bounds[1], \ box_polygon.bounds[2], box_polygon.bounds[3] # if abs(line_start_lan - bbox_xmin) < abs(bbox_xmax - line_end_lan): extend_line_lan = LineString([ (box_polygon.bounds[0], line1[1]), (box_polygon.bounds[2], line1[3]) ]) # elif abs(line_start_lon - bbox_ymin) < abs(bbox_ymax - line_end_lon): extend_line_lon = LineString([ (line2[0], box_polygon.bounds[1]), (line2[2], box_polygon.bounds[3]) ]) cond1 = raw_line_lan.intersects(raw_line_lon) cond2 = raw_line_lan.crosses(raw_line_lon) cond3 = extend_line_lan.intersects(extend_line_lon) # 十字交叉 cond4 = extend_line_lan.crosses(extend_line_lon) # 十字交叉 xp, yp = 0.0, 0.0 if cond1: (xp, yp ) = raw_line_lan.intersection(raw_line_lon).bounds[:2] elif cond3: (xp, yp) = extend_line_lan.intersection( extend_line_lon).bounds[:2] points_list.append([(xp, yp), (raw_line_lan, raw_line_lon), (extend_line_lan, extend_line_lon), box_polygon]) # TODO 验证找所有点的正确性 # template = r'F:\exam\sheet_resolve\exam_info\000000-template.xml' # tree = ET.parse(template) # for ele in points_list: # # for points2 in ele: # # points1 = points_[1][0].bounds # # points2 = points_[1][1].bounds # # create_xml(str(points_[0]), tree, int(points1[0]), int(points1[1]), int(points1[2]), int(points1[3])) # # create_xml(str(points_[0]), tree, int(points2[0]), int(points2[1]), int(points2[2]), int(points2[3])) # points2 = ele[0] # create_xml('points', tree, int(points2[0]), int(points2[1]), int(points2[0] + 1), int(points2[1] + 1)) # tree.write(os.path.join(save_path, name + '.xml')) # 找出角点最优的那个 # check points 判断点周围有没有黑色像素 points_list_x = sorted(points_list, key=lambda k: k[0][0]) sort_by_x = [ele[0] for ele in points_list_x] differ_new1 = np.array(sort_by_x[1:]) - np.array(sort_by_x[:-1]) index_new1 = sorted(list(set(np.where(differ_new1 > 10.0)[0]))) points_list_new_x = [points_list_x[ele] for ele in index_new1] points_list_y = sorted(points_list_new_x, key=lambda k: k[0][1]) sort_by_y = [ele[0] for ele in points_list_y] differ_new2 = np.array(sort_by_y[1:]) - np.array(sort_by_y[:-1]) index_new2 = sorted(list(set(np.where(differ_new2 > 10.0)[0]))) points_list_new_y = [points_list_y[ele] for ele in index_new2] print('points_list:', points_list_new_y) pixel_point_all = judge_cross_point(points_list_new_y, image, name, thresh=30)
def get_direction(points_and_lines, box_polygon, image): image_height, image_width = image.shape[:2] gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV) # raw # cv2.imwrite(os.path.join(r'E:\December\math_12_18\1_18\test_img\save3\\', 'THRESH_BINARY_INV' + '.jpg'), binary) # DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT = 1, 2, 4, 8 DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT = False, False, False, False # c++ 规则 # CROSS_TL = DIR_UP | DIR_LEFT # CROSS_TR = DIR_UP | DIR_RIGHT # CROSS_TLR = DIR_UP | DIR_LEFT | DIR_RIGHT # CROSS_BL = DIR_DOWN | DIR_LEFT # CROSS_BR = DIR_DOWN | DIR_RIGHT # CROSS_BLR = DIR_DOWN | DIR_LEFT | DIR_RIGHT # CROSS_TBL = DIR_UP | DIR_DOWN | DIR_LEFT # CROSS_TBR = DIR_UP | DIR_DOWN | DIR_RIGHT # CROSS_TBLR = DIR_UP | DIR_DOWN | DIR_LEFT | DIR_RIGHT # python 规则 # CROSS_TL = DIR_UP and DIR_LEFT # CROSS_TR = DIR_UP and DIR_RIGHT # CROSS_TLR = DIR_UP and DIR_LEFT and DIR_RIGHT # CROSS_BL = DIR_DOWN and DIR_LEFT # CROSS_BR = DIR_DOWN and DIR_RIGHT # CROSS_BLR = DIR_DOWN and DIR_LEFT and DIR_RIGHT # CROSS_TBL = DIR_UP and DIR_DOWN and DIR_LEFT # CROSS_TBR = DIR_UP and DIR_DOWN and DIR_RIGHT # CROSS_TBLR = DIR_UP and DIR_DOWN and DIR_LEFT and DIR_RIGHT # rule_list = [CROSS_TL, CROSS_TR, CROSS_TLR, CROSS_BL, CROSS_BR, CROSS_BLR, CROSS_TBL, CROSS_TBR, CROSS_TBLR] # 因为延长的线可能出问题,这里用的是原始的线 print('points_and_lines:', points_and_lines) points = points_and_lines[0] raw_line = points_and_lines[1] point_x = int(points[0]) point_y = int(points[1]) # if point_x == 1620 and point_y == 3260: bbox = box_polygon.bounds left_boarder = int(bbox[0]) - point_x if int(bbox[0]) - point_x > 0 else 0 right_boarder = int(bbox[2]) + point_x if int( bbox[2]) + point_x < image_width else image_width top_boarder = int(bbox[1]) - point_y if int(bbox[1]) - point_y > 0 else 0 bottom_boarder = int(bbox[3]) + point_y if int( bbox[3]) + point_y < image_height else image_height cv2.rectangle(image, (left_boarder, top_boarder), (right_boarder, bottom_boarder), (255, 0, 255), 1) raw_line_lan_ = raw_line[0] raw_line_lon_ = raw_line[1] if abs(raw_line_lan_.bounds[2] - point_x) >= abs(raw_line_lan_.bounds[0] - point_x): raw_line_lan = LineString([(point_x, raw_line_lan_.bounds[1]), (raw_line_lan_.bounds[2], raw_line_lan_.bounds[3])]) else: raw_line_lan = LineString([(raw_line_lan_.bounds[0], raw_line_lan_.bounds[1]), (point_x, raw_line_lan_.bounds[3])]) if abs(raw_line_lon_.bounds[3] - point_y) <= abs(point_y - raw_line_lon_.bounds[1]): raw_line_lon = LineString([(raw_line_lon_.bounds[0], raw_line_lon_.bounds[1]), (raw_line_lon_.bounds[2], point_y)]) else: raw_line_lon = LineString([(raw_line_lon_.bounds[0], point_y), (raw_line_lon_.bounds[2], raw_line_lon_.bounds[3])]) # box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]) right_area = Polygon([(point_x, point_y - 10), (right_boarder, point_y - 10), (right_boarder, point_y + 10), (point_x, point_y + 10)]) # 横线 cv2.line(image, (int(raw_line_lan.bounds[0]), int(raw_line_lan.bounds[1])), (int(raw_line_lan.bounds[2]), int(raw_line_lan.bounds[3])), (255, 0, 0), 1, cv2.LINE_AA) # cv2.line(image, (int(raw_line_lan_.bounds[0]), int(raw_line_lan_.bounds[1])), # (int(raw_line_lan_.bounds[2]), int(raw_line_lan_.bounds[3])), (255, 255, 0), 1, cv2.LINE_AA) # 纵线 cv2.line(image, (int(raw_line_lon.bounds[0]), int(raw_line_lon.bounds[1])), (int(raw_line_lon.bounds[2]), int(raw_line_lon.bounds[3])), (255, 0, 0), 1, cv2.LINE_AA) # cv2.line(image, (int(raw_line_lon_.bounds[0]), int(raw_line_lon_.bounds[1])), # (int(raw_line_lon_.bounds[2]), int(raw_line_lon_.bounds[3])), (255, 255, 0), 1, cv2.LINE_AA) cv2.rectangle(image, (int(right_area.bounds[0]), int(right_area.bounds[1])), (int(right_area.bounds[2]), int(right_area.bounds[3])), (255, 0, 255), 1) # cv2.imwrite(r'E:\December\math_12_18\1_18\test_img\save3\extend_lines_by_bbox.jpg', image) # 水平向右 decision = [ raw_line_lan.within(right_area), raw_line_lan.contains(right_area), raw_line_lan.crosses(right_area) ] if True in decision: DIR_RIGHT = True # 水平向左 left_area = Polygon([(left_boarder, point_y - 10), (point_x, point_y - 10), (point_x, point_y + 10), (left_boarder, point_y + 10)]) decision = [ raw_line_lan.within(left_area), raw_line_lan.contains(left_area), raw_line_lan.crosses(left_area) ] if True in decision: DIR_LEFT = True # box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]) # 垂直向上 top_area = Polygon([(point_x - 10, top_boarder), (point_x + 10, top_boarder), (point_x + 10, point_y), (point_x - 10, point_y)]) decision = [ raw_line_lon.within(top_area), raw_line_lon.contains(top_area), raw_line_lon.crosses(top_area) ] if True in decision: DIR_UP = True # 垂直向下 bottom_area = Polygon([(point_x - 10, point_y), (point_x + 10, point_y), (point_x + 10, bottom_boarder), (point_x - 10, bottom_boarder)]) decision = [ raw_line_lon.within(bottom_area), raw_line_lon.contains(bottom_area), raw_line_lon.crosses(bottom_area) ] if True in decision: DIR_DOWN = True CROSS_TL = DIR_UP and DIR_LEFT CROSS_TR = DIR_UP and DIR_RIGHT CROSS_TLR = DIR_UP and DIR_LEFT and DIR_RIGHT CROSS_BL = DIR_DOWN and DIR_LEFT CROSS_BR = DIR_DOWN and DIR_RIGHT CROSS_BLR = DIR_DOWN and DIR_LEFT and DIR_RIGHT CROSS_TBL = DIR_UP and DIR_DOWN and DIR_LEFT CROSS_TBR = DIR_UP and DIR_DOWN and DIR_RIGHT CROSS_TBLR = DIR_UP and DIR_DOWN and DIR_LEFT and DIR_RIGHT direction_dict = { 0: 'CROSS_TL', 1: 'CROSS_TR', 2: 'CROSS_TLR', 3: 'CROSS_BL', 4: 'CROSS_BR', 5: 'CROSS_BLR', 6: 'CROSS_TBL', 7: 'CROSS_TBR', 8: 'CROSS_TBLR', } rule_list_tmp = [ CROSS_TL, CROSS_TR, CROSS_TLR, CROSS_BL, CROSS_BR, CROSS_BLR, CROSS_TBL, CROSS_TBR, CROSS_TBLR ] index_ = np.where(np.array(rule_list_tmp) == True)[0] if len(index_) == 0: print('没找到方向:', points) return None else: print('index_:', index_) direction = direction_dict[index_[0]] return direction
class ADPolyline(object): def __init__(self, shapely_geo=None, vertices=None, use_arcpy=False, use_shapely=False): """ Can be initiated with either a shapely Linestring or a list of ADPoints (vertices) :param shapely_geo: Linestring object :param vertices: list of ADPoint objects :param use_arcpy: not implemented yet :param use_shapely: default :return: None """ if vertices is not None and shapely_geo is None: # vertices supplied, create geo # assume vertices are all ADPoint self.vertices = vertices self.__geo_from_vertices(vertices) elif vertices is None and shapely_geo is not None: # Extract vertices from shapely geo self.vertices = [] self.shapely_geo = shapely_geo # Make coordinates python friendly coord_list = list(shapely_geo.coords) if len(coord_list[0]) == 2: # 2d linestring for x, y in coord_list: vertex = ADPoint(x, y) self.vertices.append(vertex) elif len(coord_list[0]) == 3: # 3d linestring - ignore z value for x, y, _ in coord_list: vertex = ADPoint(x, y) self.vertices.append(vertex) self.first_point = self.vertices[0] self.last_point = self.vertices[-1] else: # got nothing, bail raise # Only allowed to use arcpy or shapely if use_arcpy and use_arcpy: raise if use_arcpy: raise NotImplementedError # self.geometry = arcpy.yadayada # self.point_at_distance() = arcpy.yada if use_shapely: pass self.length = self.shapely_geo.length def __geo_from_vertices(self, vertices): temp_vertices = [] for vertex in vertices: temp_vertex = (vertex.X, vertex.Y) temp_vertices.append(temp_vertex) self.shapely_geo = LineString(temp_vertices) self.first_point = self.vertices[0] self.last_point = self.vertices[-1] def __str__(self): s = '' for vertex in self.vertices: s += str(vertex) + ', ' return s[:-2] def crosses(self, line): return self.shapely_geo.crosses(line.shapely_geo) def is_same_as(self, polyline): if not isinstance(polyline, ADPolyline): raise # something if DEBUG_same_as: print 'comparing 2 polylines' for vertex1, vertex2 in zip(self.vertices, polyline.vertices): if not vertex1.is_same_as(vertex2): return False return True def intersection(self, polyline): """ Intersects self with polyline. Returns either ADPoint, list of ADPoints, or returns None :param polyline: ADPolyline :return: ADPoint, list of ADPoints or None """ new_geo = self.shapely_geo.intersection(polyline.shapely_geo) if type(new_geo) is Point: return ADPoint(shapely_geo=new_geo) elif type(new_geo) is MultiPoint: shapely_points = list(new_geo) ad_points = [] for point in shapely_points: ad_points.append(ADPoint(shapely_geo=point)) return ad_points else: return None def mid_point(self): """ Returns midpoint of self :return: ADPoint """ return self.interpolate(0.5, normalized=True) def nearest_intersection(self, line, test_point): """ Intersects self.shapely_geo with line and returns the intersection nearest to test_point If test_point is the location of an intersection it will be returned :param line: ADPolyline :param point: ADPoint :return: ADPoint """ intersects = self.intersection(line) # Check for multipoint return or no intersection if type(intersects) is ADPoint: # single intersection return intersects elif type(intersects) is None: raise UnknownIntersection('BFE doesn\'t intersect with contour') elif type(intersects) is not list: raise UnknownIntersection('Unknown return type from intersection: '+str(type(intersects))) # Assume intersects is a list of ADPoints # Sort by distance along self, relative to test_point test_dist = self.project(test_point) for point in intersects: point.station = abs(self.project(point)-test_dist) intersects.sort(key=lambda x: x.station) # Return closest point return intersects[0] def num_intersects(self, line): """ Intersects self with line. returns the number of point intersections :param line: ADPolyline :return: int """ intersect = self.intersection(line) if intersect is None: return 0 elif type(intersect) is ADPoint: return 1 elif type(intersect) is list: return len(intersect) else: # Returned polyline or something weird. Maybe raise an exception here? return 0 def point_at_distance(self, distance, normalize=False): new_pt = self.shapely_geo.interpolate(distance, normalized=normalize) return ADPoint(shapely_geo=new_pt) def distance_to(self, gis_thing): #print type(gis_thing) return self.shapely_geo.distance(gis_thing.shapely_geo) def interpolate(self, distance, normalized=False): """ Returns ADPoint at distance along polyline """ geo = self.shapely_geo.interpolate(distance, normalized) return ADPoint(shapely_geo=geo) def project(self, gis_thing): """Returns the distance along this geometric object to a point nearest the other object.""" return self.shapely_geo.project(gis_thing.shapely_geo) def plot(self, *args, **kwargs): pyplot.plot(self.shapely_geo.xy[0], self.shapely_geo.xy[1], *args, **kwargs) def label(self, text='insert text here', reverse=False, *args, **kwargs): if reverse: X = self.last_point.X Y = self.last_point.Y else: X = self.first_point.X Y = self.first_point.Y pyplot.annotate(str(text), xy=(X, Y), *args, **kwargs) def clip(self, point1, point2): """ Returns ADPolyline of the current polyline clipped between point1 and point2 Searches for loop (closed) contours and returns the shortest portion of the contour between point1 and point2 :param point1: ADPoint :param point2: ADPoint :return: ADPolyline """ # Don't screw up the real vertex order vertices = copy.copy(self.vertices) if DEBUG_contour_loop: print '..before sort start/end vertices', vertices[0], vertices[-1] # Check for loop contour if vertices[-1].is_same_as(vertices[0]): loop_flag = True else: loop_flag = False # tag existing vertices for vertex in vertices: vertex.flag = False # tag new vertices point1.flag = True point2.flag = True # calculate distances for contour vertices the fast way last_point = vertices[0] last_point.station = 0 station = 0 for vertex in vertices[1:]: station += vertex.distance(last_point) vertex.station = station last_point = vertex # calculate distances for new vertices the slow way point1.station = self.project(point1) point2.station = self.project(point2) vertices += [point1, point2] # sort the vertices vertices.sort(key=lambda x: x.station) if DEBUG_contour_loop: print '..after sort start/end vertices', vertices[0], vertices[-1] # extract middle points, keep beginning and end of line for loop calcs start_vertices = [] new_vertices = [] end_vertices = [] state = 'start' for vertex in vertices: if state == 'start' and vertex.flag is False: # not one of our points start_vertices.append(vertex) elif state == 'start' and vertex.flag is True: state = 'in' new_vertices.append(vertex) elif state == 'in' and vertex.flag is False: new_vertices.append(vertex) elif state == 'in' and vertex.flag is True: # last vertex in middle state = 'end' new_vertices.append(vertex) elif state == 'end': end_vertices.append(vertex) # outside portion of line, for loop contour tests outside_vertices = end_vertices + start_vertices[1:] if DEBUG_contour_loop: print '..len vertices = ', len(vertices) print '..len new_vertices = ', len(new_vertices) print '..line outside_vertices = ', len(outside_vertices) print '..start/end vertices', start_vertices[0], end_vertices[-1] inside_line = ADPolyline(vertices=new_vertices) # Check for loop contour if loop_flag: outside_line = ADPolyline(vertices=outside_vertices) # loop contour, see if outside is shorter if DEBUG_contour_loop: print '..loop contour' print '..outside line lenght = ', outside_line.length print '..inside line length = ', inside_line.length if outside_line.length < inside_line.length: return outside_line if DEBUG_contour_loop: print '..returning inside line' return inside_line def flip(self): self.vertices = self.vertices[::-1] self.__geo_from_vertices(self.vertices)
def createConvexPath_FD(pair): #For F_D pair only #return demand_id if ESP distance to target demand is less than fd_delivery 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 = {} if st_line.length > fd_delivery * 5280: return 0 dealtArcList = {} totalConvexPathList[odPointsList] = LineString(odPointsList) LineString terminate = 0 idx_loop1 = 0 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 no_obs = False 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(path + "graph_" + str(idx_loop1) + version_name) totalGrpah = 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 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 no_obs = True 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 = createConvexhull(obs, tLine) splitBoundary(totalConvexPathList, convexHull) convexHull = createConvexhull(obs, odPointsList) splitBoundary(totalConvexPathList, convexHull) convexHull2 = 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 = 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 = createConvexhull(obs2, [pt]) 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 = createConvexhull(labeled_multyPoly, odPointsList) 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 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 = 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 = createConvexhull(obs, tLine) 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 = 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 = createConvexhull(obs2, [pt]) 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(path + "After_graph_" + str(idx_loop1) + "_"+ str(idx_loop2) +"_"+ version_name) #end of while2 for line in impededPathList: if not totalConvexPathList.has_key(line): totalConvexPathList[line] = impededPathList[line] #totalConvexPathList.extend(impededPathList) #no obstruction if no_obs == True: return 1 totalGraph = 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(path + "totalpath" + 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(path + "ESP_" + version_name + "%d" % pair[1]) targetPysal = pysal.IOHandlers.pyShpIO.shp_file(path + "ESP_" + version_name + "%d" % pair[1]) targetShp = generateGeometry(targetPysal) total_length = 0 for line in targetShp: total_length += line.length if total_length <= fd_delivery: return 1 else: return 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') #calculate ESP distance ESP_dist = 0 for line in esp: segment = LineString(line) ESP_dist += segment.length ESP_dist = ESP_dist * 0.000189393939 #category a: less than 5 mi #b: 5~10 mi #c: 10 ~ for line in esp: w.line(parts=[[ list(x) for x in line ]]) w.record('ff') if ESP_dist <= 3.33: w.save(self.path + "a_ESP_" + self.version_name + "%d" % pair[1]) elif ESP_dist > 3.33: #and ESP_dist <= 10.005 w.save(self.path + "b_ESP_" + self.version_name + "%d" % pair[1]) #else: #w.save(self.path + "c_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)
print 'line2', line2 print 'line2 type', line2.geom_type print 'line2 coordinates:', line2.coords[:] print 'line2 length:', line2.length, '== sqrt(2)/2', line2.length==sqrt(2)/2 print '' line3 = LineString([(0,0),(-1,1)]) print 'line3', line3 print 'line3 type', line3.geom_type print 'line3 coordinates:', line3.coords[:] print 'line3 length:', line3.length, '== sqrt(2)', line3.length==sqrt(2) print '' print 'line1-line2' ipt = line1.intersection(line2) print 'ipt', ipt print 'touches:', line1.touches(line2) print 'crosses:', line1.crosses(line2) print '' print 'line1-line3' ipt = line1.intersection(line3) print 'ipt', ipt print 'touches:', line1.touches(line3) print 'crosses:', line1.crosses(line3)