def crop(self, rect): try: clipping_window_shpl = ShapelyPolygon( points_to_row_col_list(rect.corners)) self_shpl = ShapelyPolygon(self.exterior_np, holes=self.interior_np) intersections_shpl = self_shpl.buffer(0).intersection( clipping_window_shpl) mapping_shpl = mapping(intersections_shpl) except Exception: logger.warn('Polygon cropping exception, shapely.', exc_info=False) raise intersections = shapely_figure_to_coords_list(mapping_shpl) # Check for bad cropping cases (e.g. empty points list) out_polygons = [] for intersection in intersections: if isinstance(intersection, list) and len(intersection) > 0 and len( intersection[0]) >= 3: exterior = row_col_list_to_points(intersection[0], do_round=True) interiors = [] for interior_contour in intersection[1:]: if len(interior_contour) > 2: interiors.append( row_col_list_to_points(interior_contour, do_round=True)) out_polygons.append(Polygon(exterior, interiors)) return out_polygons
def percentage_intersects(self, other): if not self.intersects(other): return 0 if other.contains(self): return 1 self_polygon = ShapelyPolygon(list(self)) self_polygon_intersection = self_polygon.intersection( ShapelyPolygon(list(other))) return self_polygon_intersection.area / self_polygon.area
def guppy_distances(self): # get the intersection points of the rays with the tank walls intersections = [ ray_intersection(self.obs_pos, angle + self.obs_angle) for angle in self.bin_angles ] # construct the bins as polygons with intersection points and observer position as vertices # would surely be more efficient to just use a function which checks if a point lies within a polygon defined # by the three / four points given. self.bins = [] for i in range(len(intersections) - 1): if intersections[i][0] == intersections[ i + 1][0] or intersections[i][1] == intersections[i + 1][1]: self.bins.append( ShapelyPolygon( [self.obs_pos, intersections[i], intersections[i + 1]])) else: # if the intersection points overlap a corner of the tank, we have to add that corner to the polygon corner = addCorner(intersections[i], intersections[i + 1]) self.bins.append( ShapelyPolygon([ self.obs_pos, intersections[i], corner, intersections[i + 1] ])) # loop through the bins and find the closest guppy for each bin self.agent_view = [1000.0 for i in range(len(self.bins))] self.agent_view_angle = [0 for i in range(len(self.bins))] length = len(self.others) others_c = self.others[:] others_ang = self.others_angle[:] # Variant 1: Start with the bins and delete guppys which already found their bin # This seems to be the most efficient for i in range(len(self.bins)): j = 0 while j < length: if self.bins[i].contains( shapely.geometry.Point(others_c[j][0], others_c[j][1])): distance = dist(self.obs_pos, others_c[j]) if distance < self.agent_view[i]: self.agent_view[i] = distance ang_dif = abs(self.obs_angle - others_ang[j]) if ang_dif > pi: ang_dif = 2 * pi - ang_dif self.agent_view_angle[i] = intensity_angular(ang_dif) del (others_c[j]) del (others_ang[j]) length -= 1 else: j += 1 self.agent_view[i] = intensity_linear(self.agent_view[i])
def _as_shapely2(self, fix_self_intersections=True, warn_invalid=True): """Return a Shapely [Mulit]Polygon. Alternative to arcgis as_shapely which handles polygons with holes and fixes self-intersecting rings (as_shapely may not work properly when the python environment does not have ArcPy available). Arguments: fix_self_intersections Fix self-intersecting polygons. warn_invalid Issue a warning if polygon is invalid. """ # extract exterior and interior rings exterior_rings, interior_rings = [], [] for ring in map(_ShapelyLinearRing, self.rings): interior_rings.append(ring) if ring.is_ccw else exterior_rings.append( ring) # create polygons for each exterior ring polys = [] for exterior_ring in exterior_rings: exterior_poly = ShapelyPolygon(exterior_ring) if len(interior_rings) > 0: # determine which interior rings are within the exterior ring within_rings, outside_rings = [], [] for interior_ring in interior_rings: within_rings.append(interior_ring)\ if ShapelyPolygon(interior_ring).intersects(exterior_poly)\ else outside_rings.append(interior_ring) polys.append(ShapelyPolygon(exterior_ring, within_rings)) interior_rings = outside_rings else: polys.append(exterior_poly) if len(polys) == 1: poly_shp = ShapelyPolygon(polys[0]) else: poly_shp = ShapelyMultiPolygon(polys) # check validity and fix any self-intersecting rings if not poly_shp.is_valid: invalid_reason = _explain_validity(poly_shp) invalid_message = 'Polygon is not valid ({})'.format(invalid_reason) if 'Self-intersection' in invalid_reason and fix_self_intersections: # fix with buffer trick poly_shp = poly_shp.buffer(0.0) invalid_message += '; self-intersections were automatically fixed' if warn_invalid: invalid_message += '.' _warnings.simplefilter('always', UserWarning) _warnings.warn(invalid_message) return poly_shp
def crop(self, rect): src_exterior, src_interiors = self._get_points() ext_bbox = Rect.from_np_points(src_exterior) int_bboxes = [Rect.from_np_points(x) for x in src_interiors] if rect.intersection(ext_bbox).is_empty: return [] # optimization: non-intersected if rect.contains(ext_bbox) and all( rect.contains(x) for x in int_bboxes): return [self] # optimization: bbox contains full poly c_exterior, c_interiors = self._get_points() try: clipping_window_shpl = ShapelyPolygon(rect.to_np_points()) self_shpl = ShapelyPolygon(c_exterior, holes=c_interiors) intersections_shpl = self_shpl.buffer(0).intersection( clipping_window_shpl) mapping_shpl = mapping(intersections_shpl) except Exception: logger.warn('Polygon cropping exception, shapely.', exc_info=False) raise # logger.warn('Polygon cropping exception, shapely.', exc_info=True) # # now we are dropping the res silently # return [] # returns list of polygons, where polygon is iterable of rings (1st is exterior) # and ring is presented as tuple of (x,y)-tuples def shpl_to_coords_list(mp): if mp['type'] == 'MultiPolygon': return mp['coordinates'] elif mp['type'] == 'Polygon': return [mp['coordinates']] elif mp['type'] == 'GeometryCollection': res = [] for geom_obj in mp['geometries']: res.extend(shpl_to_coords_list(geom_obj)) return res else: return [] def clipped_to_figure(intersection): exterior = intersection[0] interiors = intersection[1:] new_obj = deepcopy(self) new_obj._set_points( exterior=np.asarray(exterior), interiors=[np.asarray(interior) for interior in interiors]) return new_obj res_polygons_pts = shpl_to_coords_list(mapping_shpl) return (clipped_to_figure(x) for x in res_polygons_pts)
def crop(self, rect): ''' Crop the current Polygon with a given rectangle, if polygon cat't be cropped it generate exception error :param rect: Rectangle class object :return: list of Poligon class objects ''' from supervisely_lib.geometry.point_location import PointLocation try: points = [ PointLocation(row=rect.top, col=rect.left), PointLocation(row=rect.top, col=rect.right + 1), PointLocation(row=rect.bottom + 1, col=rect.right + 1), PointLocation(row=rect.bottom + 1, col=rect.left) ] #points = rect.corners # old implementation with 1 pixel error (right bottom) #@TODO: investigate here (critical issue) clipping_window_shpl = ShapelyPolygon( points_to_row_col_list(points)) self_shpl = ShapelyPolygon(self.exterior_np, holes=self.interior_np) intersections_shpl = self_shpl.buffer(0).intersection( clipping_window_shpl) mapping_shpl = mapping(intersections_shpl) except Exception: logger.warn('Polygon cropping exception, shapely.', exc_info=True) # raise # if polygon is invalid, just print warning and skip it # @TODO: need more investigation here return [] intersections = shapely_figure_to_coords_list(mapping_shpl) # Check for bad cropping cases (e.g. empty points list) out_polygons = [] for intersection in intersections: if isinstance(intersection, list) and len(intersection) > 0 and len( intersection[0]) >= 3: exterior = row_col_list_to_points(intersection[0], do_round=True) interiors = [] for interior_contour in intersection[1:]: if len(interior_contour) > 2: interiors.append( row_col_list_to_points(interior_contour, do_round=True)) out_polygons.append(Polygon(exterior, interiors)) return out_polygons
def crop(self, rect): try: clipping_window = [[rect.left, rect.top], [rect.right, rect.top], [rect.right, rect.bottom], [rect.left, rect.bottom]] clipping_window_shpl = ShapelyPolygon(clipping_window) exterior = self.exterior_np[:, ::-1] intersections_polygon = LineString(exterior).intersection( clipping_window_shpl) mapping_shpl = mapping(intersections_polygon) except Exception: logger.warn('Line cropping exception, shapely.', exc_info=False) raise res_lines_pts = shapely_figure_to_coords_list(mapping_shpl) # tiny hack to combine consecutive segments lines_combined = [] for simple_l in res_lines_pts: if len(lines_combined) > 0: prev = lines_combined[-1] if prev[-1] == simple_l[0]: lines_combined[-1] = list(prev) + list(simple_l[1:]) continue lines_combined.append(simple_l) return [ Polyline(row_col_list_to_points(line)) for line in lines_combined ]
def intersect_line_polygon_shapely(line, vertices): """ Intersect a line segment with a polygon. Parameters ---------- line : couple of arrays Both end points of the line. vertices : list of arrays Vertices of the polygon. Returns ------- coords : array, shape=(2,), or [] Intersection between the line and the polygon. """ from shapely.geometry import LineString as ShapelyLineString from shapely.geometry import Polygon as ShapelyPolygon def in_line(p): for q in line: if abs(p[0] - q[0]) < 1e-5 and abs(p[1] - q[1]) < 1e-5: return True return False s_polygon = ShapelyPolygon(vertices) s_line = ShapelyLineString(line) try: coords = (array(p) for p in s_polygon.intersection(s_line).coords) coords = [p for p in coords if not in_line(p)] except NotImplementedError: coords = [] return coords
def crop(self, rect): ''' Crop the current Polyline with a given rectangle, if polyline cat't be cropped it generate exception error :param rect: Rectangle class object :return: list of Polyline class objects ''' try: clipping_window = [[rect.top, rect.left], [rect.top, rect.right], [rect.bottom, rect.right], [rect.bottom, rect.left]] clipping_window_shpl = ShapelyPolygon(clipping_window) exterior = self.exterior_np intersections_polygon = LineString(exterior).intersection( clipping_window_shpl) mapping_shpl = mapping(intersections_polygon) except Exception: logger.warn('Line cropping exception, shapely.', exc_info=False) raise res_lines_pts = shapely_figure_to_coords_list(mapping_shpl) # tiny hack to combine consecutive segments lines_combined = [] for simple_l in res_lines_pts: if len(lines_combined) > 0: prev = lines_combined[-1] if prev[-1] == simple_l[0]: lines_combined[-1] = list(prev) + list(simple_l[1:]) continue lines_combined.append(simple_l) return [ Polyline(row_col_list_to_points(line)) for line in lines_combined ]
def simplify_points(points, value=100): """ Simplify curved shapes with more than 199 points. """ from shapely.geometry import Polygon as ShapelyPolygon if len(points) > 199: factor = len(points) * value * RDD.GDSII.GRID sp = ShapelyPolygon(points).simplify(factor) points = [[p[0], p[1]] for p in sp.exterior.coords] return points
def convert2pgsql( self, ) -> Tuple[List[PlanetOsmLine], List[PlanetOsmRoads], List[PlanetOsmPolygon]]: previous_timestamp: date = self.timestamp way: PlanetOsmWays lines: List[PlanetOsmLine] = [] roads: List[PlanetOsmRoads] = [] polygons: List[PlanetOsmPolygon] = [] for way in self.ways: if not way.visible and way.timestamp: previous_timestamp = way.timestamp continue if way.tags and way.way: if way.way.closed: # create polygon with shapely & repair if needed poly: ShapelyPolygon = ShapelyPolygon(way.way.coords) if not poly.is_valid: # fix polygon poly = poly.buffer(distance=0) delete_last_terminal_line() polygon: PlanetOsmPolygon = PlanetOsmPolygon( osm_id=way.osm_id, version=way.version, way=GEOSGeometry(poly.wkt), valid_since=way.timestamp, valid_until=previous_timestamp, tags=way.tags, ) polygon = fill_osm_object(osm_object=polygon) polygon.z_order = get_z_order(tags=way.tags) polygons.append(polygon) # if not way.way.closed or way.way.closed and is_linestring(tags=way.tags): line: PlanetOsmLine = PlanetOsmLine( osm_id=way.osm_id, version=way.version, way=way.way, valid_since=way.timestamp, valid_until=previous_timestamp, tags=way.tags, ) line = fill_osm_object(osm_object=line) line.z_order = get_z_order(tags=way.tags) lines.append(line) if is_road(tags=way.tags): roads.append(line.to_road()) if way.timestamp: previous_timestamp = way.timestamp self.ways.clear() self.osm_id = None return (lines, roads, polygons)
def _orient_polygon(polygon, sign=1.0): """ A sign of 1.0 means that the coordinates of the product will be oriented counter-clockwise. Args: polygon (Union[Polygon, LinearRing]): The geometry to orient. Returns: (Union[Polygon, LinearRing]): The same type is the input, but with the points oriented so that the area matches sign. """ if isinstance(polygon, ShapelyLinearRing): polygon = ShapelyPolygon(polygon) result = _orient_polygon(polygon, sign=sign) return ShapelyLinearRing(result.exterior) exiertor = shapely_orient(polygon, sign=sign).exterior interiors = [_orient_polygon(interior, sign=sign) for interior in polygon.interiors] return ShapelyPolygon(shell=exiertor, holes=interiors)
def create_simplified_points(self): """ """ from shapely.geometry import Polygon as ShapelyPolygon value = 1 polygons = self.points self.points = [] for points in polygons: factor = (len(points) / 100) * 1e5 * value sp = ShapelyPolygon(points).simplify(factor) pp = [[p[0], p[1]] for p in sp.exterior.coords] self.points.append(pp) return self
def parse_geometry(self): ''' Find the polygon that's in this MCD product ''' tokens = LATLON.findall(self.unixtext.replace("\n", " ")) if not tokens: raise MCDException('Could not parse LAT...LON geometry') pts = [] for pair in tokens[0].split(): lat = float(pair[:4]) / 100.0 lon = 0 - float(pair[4:]) / 100.0 if lon > -40: lon = lon - 100.0 pts.append((lon, lat)) return ShapelyPolygon(pts)
def __init__(self, layer, exterior, interiors=[], net=None): # Buffer 0 forces geom cleanup self.__geometry = ShapelyPolygon(exterior, interiors).buffer(0) minx, miny, maxx, maxy = self.__geometry.bounds self.bbox = Rect.fromPoints(Point2(minx, miny), Point2(maxx, maxy)) self.net = net self.layer = layer self._project = None self.__triangulation = None
def crop(self, rect): src_exterior, _ = self._get_points() ext_bbox = Rect.from_np_points(src_exterior) if rect.intersection(ext_bbox).is_empty and (not ext_bbox.is_empty): return [] # optimization: non-intersected if rect.contains(ext_bbox): return [self] # optimization: bbox contains full poly try: clipping_window_shpl = ShapelyPolygon(rect.to_np_points()) self_shpl = LineString(src_exterior) intersections_shpl = self_shpl.intersection(clipping_window_shpl) mapping_shpl = mapping(intersections_shpl) except Exception: logger.warn('Line cropping exception, shapely.', exc_info=False) raise # returns list of polygons, where polygon is iterable of rings (1st is exterior) # and ring is presented as tuple of (x,y)-tuples def shpl_to_coords_list(mp): if mp['type'] == 'MultiLineString': return mp['coordinates'] elif mp['type'] == 'LineString': return [mp['coordinates']] elif mp['type'] == 'GeometryCollection': res = [] for geom_obj in mp['geometries']: res.extend(shpl_to_coords_list(geom_obj)) return res else: return [] def clipped_to_figure(intersection): exterior = intersection new_obj = deepcopy(self) new_obj._set_points(exterior=np.asarray(exterior)) return new_obj res_lines_pts = shpl_to_coords_list(mapping_shpl) # tiny hack to combine consequtive segments lines_combined = [] for simple_l in res_lines_pts: if len(lines_combined) > 0: prev = lines_combined[-1] if prev[-1] == simple_l[0]: lines_combined[-1] = list(prev) + list(simple_l[1:]) continue lines_combined.append(simple_l) return (clipped_to_figure(x) for x in lines_combined)
def __init__(self, layer: 'Layer', exterior: Sequence[Vec2], interiors: Sequence[Sequence[Vec2]], net: Optional['Net'] = None) -> None: super(Polygon, self).__init__() # Buffer 0 forces geom cleanup self.__geometry = ShapelyPolygon(exterior, interiors).buffer(0) minx, miny, maxx, maxy = self.__geometry.bounds self._bbox = Rect.from_points(Point2(minx, miny), Point2(maxx, maxy)) self._net = net self._layer = layer self._project: Optional['Project'] = None self.__triangulation = None
def find_polygon(self): """Search out the text for the LAT...LON polygon Returns: (str): Well Known Text (WKT) representation """ if self.action == self.CANCELS: return tokens = LATLON.findall(self.unixtext.replace("\n", " ")) if not tokens: raise SAWException('Could not parse LAT...LON geometry') pts = [] for pair in tokens[0].split(): lat = float(pair[:4]) / 100.0 lon = 0 - float(pair[4:]) / 100.0 if lon > -40: lon = lon - 100.0 pts.append((lon, lat)) return ShapelyPolygon(pts)
def publish_freespace(Publisher, LF, Header, FrameId): """ Function that publishes a Polygon message showing the current local freespace Input: 1) Publisher: PolygonStamped ROS publisher 2) LF: Local freespace polygon 3) Header: ROS header to be appended to Polygon message 4) FrameId: String defining the frame_id of the Polygon message """ # Publish freespace polygon polygon_msg = GeometryMsgsPolygon() polygon_msg.header = Header polygon_msg.header.frame_id = FrameId if LF.any() and ShapelyPolygon(LF).is_valid: numvertex = LF.shape[0] for i in range(0, numvertex): polygon_msg.polygon.points.append( Point32(x=LF[i][0], y=LF[i][1], z=0.)) else: polygon_msg.polygon.points.append(Point32(x=0., y=0., z=0.)) Publisher.publish(polygon_msg) return
def __init__(self, vertices): """ constructor for polygon, vertices must be specified in counter-clockwise order """ # shapely should not be used if the students are implementing this self.poly = ShapelyPolygon(vertices)
def contains(self, other): return ShapelyPolygon(list(self)).contains(ShapelyPolygon(list(other)))
def distance(self, point): return ShapelyPolygon(list(self)).exterior.distance( ShapelyPoint(*point))
def test_polygon(self): coordinates = [[110.0, 110.0], [110.0, 120.0], [120.0, 120.0], [120.0, 110.0], [110.0, 110.0]] from shapely.geometry import Polygon as ShapelyPolygon poly = ShapelyPolygon(coordinates)
def get_shapely_polygon(self): return ShapelyPolygon(self.points)
try: n = Neighborhood.objects.get(key=row['DB Key']) except Neighborhood.DoesNotExist: if insert_if_not_found: n = Neighborhood(name=row['Neighborhood']) n.key = row['DB Key'] else: print("No DB Key match and not inserting, continuing...") continue if row['GeoJSON'] and not pd.isna(row['GeoJSON']): if row['GeoJSON'].startswith('[[['): row['GeoJSON'] = row['GeoJSON'][1:-1] if not row['GeoJSON'].startswith('[['): row['GeoJSON'] = '[%s]' % row['GeoJSON'] geo_json = json.loads(row['GeoJSON']) print(geo_json) n.bounds = Polygon(geo_json) poly = ShapelyPolygon(geo_json) centroid = poly.centroid lat = centroid.y lng = centroid.x elif row.get('Location'): lat,lng = [x.strip() for x in row['Location'].split(',')] else: print("missing necessary data!") continue n.lat = lat n.lng = lng n.area = Area.objects.get(key=row["Area"]) n.rank = row.get('Rank') if not pd.isna(row.get('Rank')) else None n.save()
def validate(self): """Validates the current polygon's coordinate list.""" polygon = ShapelyPolygon(self._coordinates) if not polygon.is_valid(): raise ValueError('Invalid Polygon coordinates: {}'.format(self.serialize()))
def polygon_to_shapely_polygon(polygon): return ShapelyPolygon(polygon)
def plotTempature(xi, yi, zi, save_dir='.'): """ 功能: 绘制温度等值线 输入: xi: 插值格点后的经向numpy array yi: 插值格点后的纬向numpy array zi: 经过matplotlib.mlab.griddata插值后的二维numpy array 输出: save_dir/tempfile.png """ fig = plt.figure(frameon=False) ax = fig.add_subplot(111) map = Basemap(llcrnrlon=PLOTLATLON[0],llcrnrlat=PLOTLATLON[2],\ urcrnrlon=PLOTLATLON[1],urcrnrlat=PLOTLATLON[3],\ resolution='i', projection='merc', lat_0 = SJZ_Center[0], lon_0 = SJZ_Center[1]) map.readshapefile(SJZ_Shape_Path, 'sjz') # 调整格点投影坐标 x1, y1 = map(xi, yi) # 网格化经纬度网格 xx, yy = np.meshgrid(x1, y1) # print(zi.shape) # 绘图等值线 PCM = map.pcolor(xx, yy, zi, alpha=1, cmap='jet') CS = map.contour(xx, yy, zi,\ alpha=0.8, linestyles = 'dashed', levels = np.arange(np.min(zi),np.max(zi),1) ) CS_label = plt.clabel(CS, inline=True, inline_space=10, fontsize=8, fmt='%2.0f', colors='k') # print(CS.collections) # 裁剪边缘 sjz = sf.Reader(SJZ_Shape_Path) for shape_rec in sjz.shapeRecords(): # print(shape_rec.record) vertices = [] codes = [] pts = shape_rec.shape.points prt = list(shape_rec.shape.parts) + [len(pts)] for i in range(len(prt) - 1): for j in range(prt[i], prt[i+1]): vertices.append(map(pts[j][0], pts[j][1])) codes += [Path.MOVETO] codes += [Path.LINETO] * (prt[i+1] - prt[i] -2) codes += [Path.CLOSEPOLY] clip = Path(vertices, codes) clip = PathPatch(clip, transform=ax.transData) for contour in CS.collections: contour.set_clip_path(clip) clip_map_shapely = ShapelyPolygon(vertices) for text_object in CS_label: if not clip_map_shapely.contains(ShapelyPoint(text_object.get_position())): text_object.set_visible(False) PCM.set_clip_path(clip) plt.axis('off') # 保存结果图片 filePath = tempfile.mktemp(suffix='.png', prefix='tmp_', dir=save_dir) if not os.path.exists(save_dir): os.makedirs(save_dir) plt.savefig(filePath, bbox_inches='tight', pad_inches=0, transparent=True, dpi=200) return filePath
# Main part of the code, which generates and plots the RRT for Diff Drive if __name__ == "__main__": # color = [] # Selecting a default source point source = (90, 20, math.pi / 18) # List which stores the points generated in this process starting from the source pts = [source] # ur = velocity of right wheel, ul = velocity of left wheel set to a constant value '1' radians/second ur = 2 ul = 2 # This defines the obstacle area for Collision Detection which is done using "Shapely" poly = ShapelyPolygon(((5, 5), (30, 25), (38, 15), (9, 2), (5, 5))) poly2 = ShapelyPolygon(((40, 40), (60, 60), (50, 40), (60, 20), (40, 40))) poly3 = ShapelyPolygon(((38, 70), (58, 70), (58, 95), (38, 90), (38, 70))) poly4 = ShapelyPolygon(((5, 40), (25, 40), (25, 60), (5, 60), (5, 40))) poly5 = ShapelyPolygon( ((70, 60), (100, 60), (100, 90), (70, 90), (70, 60))) polygons = ShapelyMultiPolygon([poly, poly2, poly3, poly4, poly5]) # This list is to store the points which are used in RRT generation lines = [] # This list is used to store the points leading to the destination forming shortest path lines2 = [] # for i in range(12): # color.append((1, 0, 0, 1)) # This iterates for a specified number of times, in each iteration performs a set of tasks to get a newpoint for building the RRT
def intersects(self, other): return ShapelyPolygon(list(self)).intersects( ShapelyPolygon(list(other)))