def compute_repulsive_ws(self, control_point, obstacle): point, _, eta = control_point # need to unpack obstacle tuple into polygon and threshold obstacle_poly = obstacle[0] obstacle_thresh = obstacle[1] d2obstacle = point.distance(obstacle_poly) # this is straight from book if d2obstacle > obstacle_thresh: return Point(0, 0) else: # scalar is length of vector that points away from closest obstacle # point scalar = eta * ((obstacle_thresh ** -1) - (d2obstacle ** -1)) * (d2obstacle ** -2) # construct gradient vector # find closest point, you can ignore the details Yinan pol_ext = obstacle_poly if obstacle_poly.geom_type != "LineString": pol_ext = LinearRing(obstacle_poly.exterior.coords) d = pol_ext.project(point) p = pol_ext.interpolate(d) # closest point c = Point(list(p.coords)[0]) dqc = c.distance(point) # from book, formula for delta vector delta_d_i = Point(((point.x - c.x) / dqc, (point.y - c.y) / dqc)) return Point((-1 * delta_d_i.x * scalar, -1 * delta_d_i.y * scalar))
def point_to_follow(poly, point, dist): """point in the boundar, that is after """ pol_ext = LinearRing(poly.exterior.coords) d = pol_ext.project(point) + dist p = pol_ext.interpolate(d ) closest = list(p.coords)[0] return closest
def closest_on_polygon(poly, point): """Closest point in a polygon to an external point """ pol_ext = LinearRing(poly.exterior.coords) d = pol_ext.project(point) p = pol_ext.interpolate(d) closest = list(p.coords)[0] return closest
def point_in_polygon(point, region): from shapely.geometry import ( Polygon, LinearRing, Point, ) point = Point(point) polygon_boundary = LinearRing(region) polygon = Polygon(region) return polygon.contains(point) or polygon_boundary.contains(point)
def test_equals_argument_order(self): """ Test equals predicate functions correctly regardless of the order of the inputs. See issue #317. """ coords = ((0, 0), (1, 0), (1, 1), (0, 0)) ls = LineString(coords) lr = LinearRing(coords) self.assertFalse(ls.__eq__(lr)) # previously incorrectly returned True self.assertFalse(lr.__eq__(ls)) self.assertFalse(ls == lr) self.assertFalse(lr == ls) ls_clone = LineString(coords) lr_clone = LinearRing(coords) self.assertTrue(ls.__eq__(ls_clone)) self.assertTrue(lr.__eq__(lr_clone)) self.assertTrue(ls == ls_clone) self.assertTrue(lr == lr_clone)
def get_inside_target (self, x_utm, y_utm): ''' method to get a waypoint coordinates of a point inside the safety zone. This first creates a buffer on the geofence that is slightly inside of the safety zone, and then gets the closest point on that linear ring. This is returned as an interim waypoint. The point needs to be slightly inside of the safety zone so that when we reach the point it immediately relaxes to being within the safety zone, and any excursions can be tagged properly. x_utm = the x_utm point to work from (usually the point where the boat is now) y_utm = the y_utm point to work from (usually the point where the boat is now) ''' # create polygon that is inside of the safety zone by the maximum GPS error if self.bs['lat_error'] > self.bs['long_error']: max_gps_error = self.bs['lat_error'] else: max_gps_error = self.bs['long_error'] # check the error is not more than 10 m to ensure we don't cause issues with # making the safetyzone buffer too small and it returning a point. if max_gps_error > 10.0: max_gps_error = 10.0 try: # perform buffer on safetyzone inside_poly = self.safetyzone.buffer (distance = -1.0 * max_gps_error) # find the closest point along the inside_poly polygon eval_point = Point ([x_utm, y_utm]) exterior = LinearRing (inside_poly.exterior) dist = exterior.project (eval_point) close_point = exterior.interpolate (dist) x_utm_target = close_point.coords[0][0] y_utm_target = close_point.coords[0][1] except: # find the closest point along the safetyzone polygon instead as a fallback eval_point = Point ([x_utm, y_utm]) exterior = LinearRing (self.safetyzone.exterior) dist = exterior.project (eval_point) close_point = exterior.interpolate (dist) x_utm_target = close_point.coords[0][0] y_utm_target = close_point.coords[0][1] return (x_utm_target, y_utm_target)
def closest_to(point, poly): pol_ext = LinearRing(poly.exterior.coords) d = pol_ext.project(point) p = pol_ext.interpolate(d) closest_point_coords = list(p.coords)[0] return closest_point_coords
def get_xy_from_nt(n: float, t: float, centerline: np.ndarray) -> Tuple[float, float]: """Convert a single n-t coordinate (centerline curvilinear coordinate) to absolute x-y. Args: n (float): Offset from centerline t (float): Distance along the centerline centerline (numpy array): Centerline coordinates Returns: x1 (float): x-coordinate in map frame y1 (float): y-coordinate in map frame """ line_string = LineString(centerline) # If distance along centerline is negative, keep it to the start of line point_on_cl = line_string.interpolate( t) if t > 0 else line_string.interpolate(0) local_ls = None # Find 2 consective points on centerline such that line joining those 2 points # contains point_on_cl for i in range(len(centerline) - 1): pt1 = centerline[i] pt2 = centerline[i + 1] ls = LineString([pt1, pt2]) if ls.distance(point_on_cl) < 1e-8: local_ls = ls break assert local_ls is not None, "XY from N({}) T({}) not computed correctly".format( n, t) pt1, pt2 = local_ls.coords[:] x0, y0 = point_on_cl.coords[0] # Determine whether the coordinate lies on left or right side of the line formed by pt1 and pt2 # Find a point on either side of the line, i.e., (x1_1, y1_1) and (x1_2, y1_2) # If the ring formed by (pt1, pt2, (x1_1, y1_1)) is counter clockwise, then it lies on the left # Deal with edge cases # Vertical if pt1[0] == pt2[0]: m = 0 x1_1, x1_2 = x0 + n, x0 - n y1_1, y1_2 = y0, y0 # Horizontal elif pt1[1] == pt2[1]: m = float("inf") x1_1, x1_2 = x0, x0 y1_1, y1_2 = y0 + n, y0 - n # General case else: ls_slope = (pt2[1] - pt1[1]) / (pt2[0] - pt1[0]) m = -1 / ls_slope x1_1 = x0 + n / math.sqrt(1 + m**2) y1_1 = y0 + m * (x1_1 - x0) x1_2 = x0 - n / math.sqrt(1 + m**2) y1_2 = y0 + m * (x1_2 - x0) # Rings formed by pt1, pt2 and coordinates computed above lr1 = LinearRing([pt1, pt2, (x1_1, y1_1)]) lr2 = LinearRing([pt1, pt2, (x1_2, y1_2)]) # If ring is counter clockwise if lr1.is_ccw: x_ccw, y_ccw = x1_1, y1_1 x_cw, y_cw = x1_2, y1_2 else: x_ccw, y_ccw = x1_2, y1_2 x_cw, y_cw = x1_1, y1_1 # If offset is positive, coordinate on the left if n > 0: x1, y1 = x_ccw, y_ccw # Else, coordinate on the right else: x1, y1 = x_cw, y_cw return x1, y1
def test_parallel_offset_linear_ring(self): lr1 = LinearRing([(0, 0), (5, 0), (5, 5), (0, 5), (0, 0)]) self.assertEqual(lr1.parallel_offset(2, 'left', resolution=1), LineString([(2, 2), (3, 2), (3, 3), (2, 3), (2, 2)]))
def get_rectification_ransac(line_hough, frame=[], N=500, tol=0.02): """ lines = list of tuples (rho, theta) of lines """ if len(line_hough) < 4: return None, None, None lines = get_line_pairs(line_hough) line_pairs = np.array(lines, dtype=np.float32) lines_first = np.array([line_pairs[:, 0, :]]) lines_second = np.array([line_pairs[:, 1, :]]) lines_g1_b = np.abs(line_hough[:, 0, 1] - np.pi / 2) < np.pi / 8 lines_g1 = np.flatnonzero(lines_g1_b) lines_g2_b = np.abs(line_hough[:, 0, 1] - np.pi) < np.pi / 4 lines_g2 = np.flatnonzero(lines_g2_b) if lines_g1.size < 2 or lines_g2.size < 2: return None, None, None, None, None # plt.scatter(line_hough[np.logical_not(np.logical_or(lines_g1_b, lines_g2_b)),0,0], line_hough[np.logical_not(np.logical_or(lines_g1_b, lines_g2_b)),0,1], c='b') # plt.scatter(line_hough[lines_g1,0,0], line_hough[lines_g1,0,1], c='r') # plt.scatter(line_hough[lines_g2,0,0], line_hough[lines_g2,0,1], c='g') # plt.show() rect_pts = np.array( ((0, 0), (100, 0), (100, 100), (0, 100)), dtype=np.float32) + 100 horz_idx = [] vert_idx = [] uniq = 0 H = [] animate = len(frame) > 0 for _ in range(N): # ran_lines = np.random.choice(range(len(line_pairs)), 4, replace=False) ran_g1 = np.random.choice(lines_g1, 2, replace=False) if line_hough[ran_g1[0], 0, 1] < line_hough[ran_g1[1], 0, 1]: ran_g1 = ran_g1[::-1] ran_g2 = np.random.choice(lines_g2, 2, replace=False) if line_hough[ran_g2[0], 0, 1] < line_hough[ran_g2[1], 0, 1]: ran_g2 = ran_g2[::-1] ran_lines = np.concatenate([ran_g1, ran_g2]) ran_strings = [LineString(line_pairs[r]) for r in ran_lines] pts_geom = [ ran_strings[0].intersection(ran_strings[2 + 0]), ran_strings[1].intersection(ran_strings[2 + 0]), ran_strings[1].intersection(ran_strings[2 + 1]), ran_strings[0].intersection(ran_strings[2 + 1]) ] try: pts = np.array([(pt.x, pt.y) for pt in pts_geom], dtype=np.float32) except AttributeError: # one of them is not a point continue # Avoid self-intersections ring = LinearRing(pts) if not ring.is_simple: continue skip = False for j in range(len(pts_geom)): if pts_geom[j].distance(pts_geom[(j + 1) % len(pts_geom)]) < 10: skip = True if skip: continue if not ring.is_ccw: pts = pts[::-1] if animate: cur_frame = np.array(frame, copy=True) for j in range(len(line_pairs)): color = (255, 0, 0) if j in ran_lines[0:2]: color = (0, 0, 255) elif j in ran_lines[2:]: color = (0, 255, 255) cv2.line(cur_frame, tuple(lines_first[0, j, :]), tuple(lines_second[0, j, :]), color) cv2.circle(cur_frame, tuple(pts[0]), 3, (255, 0, 0)) cv2.circle(cur_frame, tuple(pts[1]), 3, (255, 0, 0)) cv2.circle(cur_frame, tuple(pts[2]), 3, (255, 0, 0)) cv2.circle(cur_frame, tuple(pts[3]), 3, (255, 0, 0)) cv2.imshow("Selected lines", cur_frame) cur_H = cv2.getPerspectiveTransform(pts, rect_pts) lines1 = np.squeeze(cv2.perspectiveTransform(lines_first, cur_H)) lines2 = np.squeeze(cv2.perspectiveTransform(lines_second, cur_H)) cur_horz_idx = [] cur_vert_idx = [] for j in range(len(lines1)): dx = lines1[j][0] - lines2[j][0] dy = lines1[j][1] - lines2[j][1] if abs(dy / dx) < tol: cur_horz_idx.append(j) elif abs(dx / dy) < tol: cur_vert_idx.append(j) # xs = line_pairs[cur_vert_idx, :, 0].ravel() # ys = line_pairs[cur_horz_idx, :, 1].ravel() # width = np.max(xs) - np.min(xs) # height = np.max(ys) - np.min(ys) def get_unique_lines(idx, lines1, lines2): uniq = [] uniq_idx = [] for j in range(len(idx)): big_line = LineString([lines1[j], lines2[j]]).buffer(1) add = True for uniq_line in uniq: if big_line.intersects(uniq_line): add = False break if add: uniq.append(big_line) uniq_idx.append(j) return uniq_idx uniq_horz_lines = get_unique_lines(cur_horz_idx, lines1, lines2) uniq_vert_lines = get_unique_lines(cur_vert_idx, lines1, lines2) if len(uniq_horz_lines) + len(uniq_vert_lines) > uniq: horz_idx = cur_horz_idx vert_idx = cur_vert_idx H = cur_H uniq = len(uniq_horz_lines) + len(uniq_vert_lines) # print 'Update: ', H, ' horz=', len(horz_idx), ' vert=', len(vert_idx), ' uniq=', uniq if animate: rect_frame = np.zeros(cur_frame.shape, dtype=cur_frame.dtype) for j in range(len(lines1)): color = (255, 0, 0) if j in ran_lines[0:2]: color = (0, 0, 255) elif j in ran_lines[2:]: color = (0, 255, 255) elif j in cur_horz_idx or j in cur_vert_idx: color = (255, 255, 0) cv2.line(rect_frame, tuple(lines1[j, :]), tuple(lines2[j, :]), color) cv2.imshow("Rectified shape", rect_frame) cv2.waitKey() if len(H) > 0: lines1 = np.squeeze(cv2.perspectiveTransform(lines_first, H)) lines2 = np.squeeze(cv2.perspectiveTransform(lines_second, H)) return H, horz_idx, vert_idx, lines1, lines2 else: return None, None, None, None, None
def parse_query(self, query): super().parse_query(query) if len(self.variables) > 1: raise ClientError(f"MapPlotter only supports 1 variable. \ Received multiple: {self.variables}") self.projection = query.get("projection") self.area = query.get("area") names = [] centroids = [] all_rings = [] data = None for idx, a in enumerate(self.area): if isinstance(a, str): sp = a.split("/", 1) if data is None: data = list_areas(sp[0], simplify=False) b = [x for x in data if x.get("key") == a] a = b[0] self.area[idx] = a else: self.points = copy.deepcopy(np.array(a["polygons"])) a["polygons"] = self.points.tolist() a["name"] = " " rings = [LinearRing(po) for po in a["polygons"]] if len(rings) > 1: u = cascaded_union(rings) else: u = rings[0] all_rings.append(u) if a.get("name"): names.append(a.get("name")) centroids.append(u.centroid) nc = sorted(zip(names, centroids)) self.names = [n for (n, c) in nc] self.centroids = [c for (n, c) in nc] data = None if len(all_rings) > 1: combined = cascaded_union(all_rings) else: combined = all_rings[0] self.combined_area = combined combined = combined.envelope self.centroid = list(combined.centroid.coords)[0] self.bounds = combined.bounds self.show_bathymetry = bool(query.get("bathymetry")) self.show_area = bool(query.get("showarea")) self.quiver = query.get("quiver") self.contour = query.get("contour")
# run using ctrl + alt + N # Constants ########### R = 0.02 # radius of wheels in meters L = 0.094 # distance between wheels in meters W = 1.15 # width of arena H = 1.95 # height of arena robot_timestep = 0.1 # 1/robot_timestep equals update frequency of robot simulation_timestep = 0.01 # timestep in kinematics sim (probably don't touch..) # the world is a rectangular arena with width W and height H world = LinearRing([(W / 2, H / 2), (-W / 2, H / 2), (-W / 2, -H / 2), (W / 2, -H / 2)]) # Variables ########### x = 0.3 # robot position in meters - x direction y = 0.0 # robot position in meters - y direction q = pi/2 # robot heading with respect to x-axis in radians left_wheel_velocity = 10 / (2 * pi) # robot left wheel velocity in radians/s right_wheel_velocity = 10 / (2 * pi) # robot right wheel velocity in radians/s # Q-Learning Set-up #################### gamma = 0.75 # discount factor alpha = 0.9 # learning rate
def test_exterior(self): exp_exterior = GeoSeries([LinearRing(p.boundary) for p in self.g3]) for expected, computed in zip(exp_exterior, self.g3.exterior): assert computed.equals(expected)
def _linearring(geom, projector): return LinearRing(projector(*geom.coords.xy).T)
import random #run using ctrl + alt + N # Constants ########### R = 0.02 # radius of wheels in meters L = 0.094 # distance between wheels in meters W = 1.15 # width of arena H = 1.95 # height of arena robot_timestep = 0.1 # 1/robot_timestep equals update frequency of robot simulation_timestep = 0.01 # timestep in kinematics sim (probably don't touch..) # the world is a rectangular arena with width W and height H world = LinearRing([(W / 2, H / 2), (-W / 2, H / 2), (-W / 2, -H / 2), (W / 2, -H / 2)]) # Variables ########### x = 0.0 # robot position in meters - x direction y = 0.0 # robot position in meters - y direction q = 0.0 # robot heading with respect to x-axis in radians left_wheel_velocity = 10 / (2 * pi) # robot left wheel velocity in radians/s right_wheel_velocity = 10 / (2 * pi) # robot right wheel velocity in radians/s # Kinematic model ################# # updates robot position and heading based on velocity of wheels and the elapsed time
def place_cameras_2d(cameras, environment, color='c', tgt_steps=20): """ Plots a list of cameras as 2D gradient cones in the most recently open plot :param cameras: a list of Camera objects corresponding to the cameras which have already been placed in an environment :param environment: an Environment class instance :param color: color of the camera cones to be plotted :param tgt_steps: number of steps over which discrete gradient should be plotted :return: """ if environment.obstacles is None: for camera in cameras: fill_cone_gradient_2d(pose=np.array( [camera.pose[0], camera.pose[1], camera.pose[-1]]), fov=camera.fov, camera_range=camera.range, b=camera.b, n=camera.n, alphas=camera.score_range, color=color) else: for i in range(len(cameras)): # break FOV into ~20 triangles dth = cameras[i].fov[0] / tgt_steps angles = np.linspace( cameras[i].pose[-1] - cameras[i].fov[0] / 2 + dth / 2, cameras[i].pose[-1] + cameras[i].fov[0] / 2 - dth / 2, tgt_steps) sub_pose = cameras[i].pose.copy() for th in angles: r_ = cameras[i].range.copy( ) # reset range for each sub-segment sub_pose[-1] = th R = rot2d(th) end_point = sub_pose[:2] + np.dot(R, np.array([r_[-1], 0])) line = LineString(np.array([sub_pose[:2], end_point])) dist_to_obs = np.inf for obs in environment.obstacles: obs_edges = LinearRing(obs) intersection = obs_edges.intersection(line) if intersection.type == 'Point': # single intersection... d = intersection.distance(Point(sub_pose[:2])) dist_to_obs = np.min([d, dist_to_obs]) elif intersection.type == 'MultiPoint': # double intersection... for p in intersection: d = p.distance(Point(sub_pose[:2])) dist_to_obs = np.min([d, dist_to_obs]) for e in range(len(r_)): r_[e] = np.min([r_[e], dist_to_obs]) if r_[-1] != cameras[i].range[-1]: # compute new alpha values. default is 1 to 0.1 between r[0] and r[1] b, n = get_inv_sqr_coefficients(cameras[i].range, np.array([1, 0.1])) alpha_r_ = n / np.power(r_[-1] - b, 2) a_ = np.array([1, alpha_r_]) else: a_ = np.array([1, 0.1]) fill_cone_gradient_2d(pose=np.array( [sub_pose[0], sub_pose[1], sub_pose[-1]]), fov=dth, camera_range=r_, alphas=a_, color=color)
def test_linear_ring(): ls = LinearRing([(0.5, 0.5), (1.5, 0.5), (1.5, 1.5), (0.5, 1.5), (0.5, 0.5)]) expected = { 0: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((0.5, 0.5), (1.0, 0.5)), ((0.5, 1.0), (0.5, 0.5))) } }, 1: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((1.0, 1.5), (0.5, 1.5), (0.5, 1.0)), ) } }, 2: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((1.0, 0.5), (1.5, 0.5), (1.5, 1.0)), ) } }, 3: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((1.5, 1.0), (1.5, 1.5), (1.0, 1.5)), ) } } } result = get_intersection(ls, 'line', Map(grid, 'name'), (0, 1, 2, 3), to_meters=False) assert result == expected expected = { 0: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((0.5, 0.5), (1.0, 0.5)), ((0.5, 1.0), (0.5, 0.5))) } }, 1: { 'measure': 1, 'geom': { 'type': 'MultiLineString', 'coordinates': (((1.0, 1.5), (0.5, 1.5), (0.5, 1.0)), ) } } } assert get_intersection(ls, 'line', Map(grid, 'name'), (0, 1), to_meters=False) == expected
shapely_betterproto_serializer as topb, shapely_betterproto_deserializer as to_shapely, ) from shapely.geometry import ( LineString, Point, MultiLineString, LinearRing, GeometryCollection, ) from shapely_grpc_io import geometry_pb2 as pb2 line = LineString(((1.0, 2.0), (3.0, 4.0))) p = Point(1.0, 2.0, 3.0) geom = MultiLineString((((1.0, 2.0), (3.0, 4.0)), )) ring = LinearRing(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0))) def test_geometrycollection_serialization(): coll = GeometryCollection([p, geom, ring]) coll_proto = topb.serialize(coll) deserialized = to_shapely.deserialize(coll_proto) assert type(deserialized) is GeometryCollection assert deserialized.equals(coll) def test_geometrycollection_in_geometrycollection():
def observation_point_v1_0(query: str): """ API Format: /api/v1.0/observation/point/<string:query>.json <string:query> : List of key=value pairs, seperated by ; valid query keys are: start_date, end_date, datatype, platform_type, meta_key, meta_value, mindepth, maxdepth, area, radius Observational query for points **Used in ObservationSelector** """ query_dict = { key: value for key, value in [ q.split('=') for q in query.split(';')] } data = [] max_age = 86400 params = {} MAPPING = { 'start_date': 'starttime', 'end_date': 'endtime', 'datatype': 'variable', 'platform_type': 'platform_types', 'meta_key': 'meta_key', 'meta_value': 'meta_value', 'mindepth': 'mindepth', 'maxdepth': 'maxdepth', } for k,v in query_dict.items(): if k not in MAPPING: continue if k in ['start_date', 'end_date']: params[MAPPING[k]] = dateparse(v) elif k in ['datatype', 'meta_key', 'meta_value']: if k == 'meta_key' and v == 'Any': continue if k == 'meta_value' and query_dict.get('meta_key') == 'Any': continue params[MAPPING[k]] = v elif k == 'platform_type': params[MAPPING[k]] = v.split(',') else: params[MAPPING[k]] = float(v) checkpoly = False with_radius = False if 'area' in query_dict: area = json.loads(query_dict.get('area')) if len(area) > 1: lats = [c[0] for c in area] lons = [c[1] for c in area] params['minlat'] = min(lats) params['minlon'] = min(lons) params['maxlat'] = max(lats) params['maxlon'] = max(lons) poly = Polygon(LinearRing(area)) checkpoly = True else: params['latitude'] = area[0][0] params['longitude'] = area[0][1] params['radius'] = float(query_dict.get('radius', 10)) with_radius = True if with_radius: stations = ob_queries.get_stations_radius(session=DB.session, **params) else: stations = ob_queries.get_stations(session=DB.session, **params) if len(stations) > 500: stations = stations[::round(len(stations)/500)] for s in stations: if checkpoly and not poly.contains(Point(s.latitude, s.longitude)): continue d = { 'type': "Feature", 'geometry': { 'type': "Point", 'coordinates': [s.longitude, s.latitude] }, 'properties': { 'type': s.platform.type.name, 'id': s.id, 'class': 'observation', } } if s.name: d['properties']['name'] = s.name data.append(d) result = { 'type': "FeatureCollection", 'features': data, } resp = jsonify(result) resp.cache_control.max_age = max_age return resp
class WCARaceGeometry(gym.Env): sps = 50 rate = 5 front_dist = 800 front_step = 100 trail_dist = 104 trail_step = 13 starting_proj = 1710 max_damage = 100 def __init__(self, host='localhost', port=64256): self.steps = WCARaceGeometry.sps // WCARaceGeometry.rate self.host = host self.port = port self.action_space = self._action_space() self.observation_space = self._observation_space() self.episode_steps = 0 self.spine = None self.l_edge = None self.r_edge = None self.polygon = None front_factor = WCARaceGeometry.front_dist / WCARaceGeometry.front_step trail_factor = WCARaceGeometry.trail_dist / WCARaceGeometry.trail_step self.front = lambda step: +front_factor * step self.trail = lambda step: -trail_factor * step self.bng = BeamNGpy(self.host, self.port) self.vehicle = Vehicle('racecar', model='sunburst', licence='BEAMNG', colour='red', partConfig='vehicles/sunburst/hillclimb.pc') electrics = Electrics() damage = Damage() self.vehicle.attach_sensor('electrics', electrics) self.vehicle.attach_sensor('damage', damage) scenario = Scenario('west_coast_usa', 'wca_race_geometry_v0') scenario.add_vehicle(self.vehicle, pos=(394.5, -247.925, 145.25), rot=(0, 0, 90)) scenario.make(self.bng) self.bng.open(launch=True) self.bng.set_deterministic() self.bng.set_steps_per_second(WCARaceGeometry.sps) self.bng.load_scenario(scenario) self._build_racetrack() self.observation = None self.last_observation = None self.last_spine_proj = None self.bng.start_scenario() self.bng.pause() def __del__(self): self.bng.close() def _build_racetrack(self): roads = self.bng.get_roads() track = roads['race_ref'] l_vtx = [] s_vtx = [] r_vtx = [] for right, middle, left in track: r_vtx.append(right) s_vtx.append(middle) l_vtx.append(left) self.spine = LinearRing(s_vtx) self.r_edge = LinearRing(r_vtx) self.l_edge = LinearRing(l_vtx) r_vtx = [v[0:2] for v in r_vtx] l_vtx = [v[0:2] for v in l_vtx] self.polygon = Polygon(l_vtx, holes=[r_vtx]) def _action_space(self): action_lo = [-1., -1.] action_hi = [+1., +1.] return gym.spaces.Box(np.array(action_lo), np.array(action_hi), dtype=float) def _observation_space(self): # n vertices of left and right polylines ahead and behind, 3 floats per # vtx scope = WCARaceGeometry.trail_step + WCARaceGeometry.front_step obs_lo = [ -np.inf, ] * scope * 3 obs_hi = [ np.inf, ] * scope * 3 obs_lo.extend([ -np.inf, # Distance to left edge -np.inf, # Distance to right edge -2 * np.pi, # Inclination -2 * np.pi, # Angle -2 * np.pi, # Vertical angle -np.inf, # Spine speed 0, # RPM -1, # Gear 0, # Throttle 0, # Brake -1.0, # Steering 0, # Wheel speed -np.inf, # Altitude ]) obs_hi.extend([ np.inf, # Distance to left edge np.inf, # Distance to right edge 2 * np.pi, # Inclincation 2 * np.pi, # Angle 2 * np.pi, # Vertical angle np.inf, # Spine speed np.inf, # RPM 8, # Gear 1.0, # Throttle 1.0, # Brake 1.0, # Steering np.inf, # Wheel speed np.inf, # Altitude ]) return gym.spaces.Box(np.array(obs_lo), np.array(obs_hi), dtype=float) def _make_commands(self, action): brake = 0 throttle = action[1] steering = action[0] if throttle < 0: brake = -throttle throttle = 0 self.vehicle.control(steering=steering, throttle=throttle, brake=brake) def _project_vehicle(self, pos): r_proj = self.r_edge.project(pos) r_proj = self.r_edge.interpolate(r_proj) l_proj = self.l_edge.project(r_proj) l_proj = self.l_edge.interpolate(l_proj) s_proj = self.spine.project(r_proj) s_proj = self.spine.interpolate(s_proj) return l_proj, s_proj, r_proj def _get_vehicle_angles(self, vehicle_pos, spine_seg): spine_beg = spine_seg.coords[+0] spine_end = spine_seg.coords[-1] spine_angle = np.arctan2(spine_end[1] - spine_beg[1], spine_end[0] - spine_beg[0]) vehicle_angle = self.vehicle.state['dir'][0:2] vehicle_angle = np.arctan2(vehicle_angle[1], vehicle_angle[0]) vehicle_angle = normalise_angle(vehicle_angle - spine_angle) vehicle_angle -= np.pi elevation = np.arctan2(spine_beg[2] - spine_end[2], spine_seg.length) vehicle_elev = self.vehicle.state['dir'] vehicle_elev = np.arctan2(vehicle_elev[2], np.linalg.norm(vehicle_elev)) return vehicle_angle, vehicle_elev, elevation def _wrap_length(self, target): length = self.spine.length while target < 0: target += length while target > length: target -= length return target def _gen_track_scope_loop(self, it, fn, base, s_scope, s_width): for step in it: distance = base + fn(step) distance = self._wrap_length(distance) s_proj = self.spine.interpolate(distance) s_scope.append(s_proj) l_proj = self.l_edge.project(s_proj) l_proj = self.l_edge.interpolate(l_proj) r_proj = self.r_edge.project(s_proj) r_proj = self.r_edge.interpolate(r_proj) width = l_proj.distance(r_proj) s_width.append(width) def _gen_track_scope(self, pos, spine_seg): s_scope = [] s_width = [] base = self.spine.project(pos) it = range(WCARaceGeometry.trail_step, 0, -1) self._gen_track_scope_loop(it, self.trail, base, s_scope, s_width) it = range(1) self._gen_track_scope_loop(it, lambda x: x, base, s_scope, s_width) it = range(WCARaceGeometry.front_step + 1) self._gen_track_scope_loop(it, self.front, base, s_scope, s_width) s_proj = self.spine.interpolate(base) offset = (-s_proj.x, -s_proj.y, -s_proj.z) s_line = LineString(s_scope) s_line = affinity.translate(s_line, *offset) spine_beg = spine_seg.coords[+0] spine_end = spine_seg.coords[-1] direction = [spine_end[i] - spine_beg[i] for i in range(3)] angle = np.arctan2(direction[1], direction[0]) + np.pi / 2 s_line = affinity.rotate(s_line, -angle, origin=(0, 0), use_radians=True) ret = list() s_scope = s_line.coords for idx in range(1, len(s_scope) - 1): curvature = calculate_curvature(s_scope, idx) inclination = calculate_inclination(s_scope, idx) width = s_width[idx] ret.append(curvature) ret.append(inclination) ret.append(width) return ret def _spine_project_vehicle(self, vehicle_pos): proj = self.spine.project(vehicle_pos) - WCARaceGeometry.starting_proj if proj < 0: proj += self.spine.length proj = self.spine.length - proj return proj def _get_spine_speed(self, vehicle_pos, vehicle_dir, spine_seg): spine_beg = spine_seg.coords[0] future_pos = Point(vehicle_pos.x + vehicle_dir[0], vehicle_pos.y + vehicle_dir[1], vehicle_pos.z + vehicle_dir[2]) spine_end = self.spine.project(future_pos) spine_end = self.spine.interpolate(spine_end) return spine_end.distance(Point(*spine_beg)) def _make_observation(self, sensors): electrics = sensors['electrics']['values'] vehicle_dir = self.vehicle.state['dir'] vehicle_pos = self.vehicle.state['pos'] vehicle_pos = Point(*vehicle_pos) spine_beg = self.spine.project(vehicle_pos) spine_end = spine_beg spine_end += WCARaceGeometry.front_dist / WCARaceGeometry.front_step spine_beg = self.spine.interpolate(spine_beg) spine_end = self.spine.interpolate(spine_end) spine_seg = LineString([spine_beg, spine_end]) spine_speed = self._get_spine_speed(vehicle_pos, vehicle_dir, spine_seg) l_dist = self.l_edge.distance(vehicle_pos) r_dist = self.r_edge.distance(vehicle_pos) angle, vangle, elevation = self._get_vehicle_angles( vehicle_pos, spine_seg) l_proj, s_proj, r_proj = self._project_vehicle(vehicle_pos) s_scope = self._gen_track_scope(vehicle_pos, spine_seg) obs = list() obs.extend(s_scope) obs.append(l_dist) obs.append(r_dist) obs.append(elevation) obs.append(angle) obs.append(vangle) obs.append(spine_speed) obs.append(electrics['rpm']) obs.append(electrics['gearIndex']) obs.append(electrics['throttle']) obs.append(electrics['brake']) obs.append(electrics['steering']) obs.append(electrics['wheelspeed']) obs.append(electrics['altitude']) return np.array(obs) def _compute_reward(self, sensors): damage = sensors['damage'] vehicle_pos = self.vehicle.state['pos'] vehicle_pos = Point(*vehicle_pos) if damage['damage'] > WCARaceGeometry.max_damage: return -1, True if not self.polygon.contains(Point(vehicle_pos.x, vehicle_pos.y)): return -1, True score, done = -1, False spine_proj = self._spine_project_vehicle(vehicle_pos) if self.last_spine_proj is not None: diff = spine_proj - self.last_spine_proj if diff >= -0.10: if diff < 0.5: return -1, False else: score, done = diff / self.steps, False elif np.abs(diff) > self.spine.length * 0.95: score, done = 1, True else: score, done = -1, True self.last_spine_proj = spine_proj return score, done def reset(self): self.episode_steps = 0 self.vehicle.control(throttle=0, brake=0, steering=0) self.bng.restart_scenario() self.bng.step(30) self.bng.pause() self.vehicle.set_shift_mode(3) self.vehicle.control(gear=2) sensors = self.bng.poll_sensors(self.vehicle) self.observation = self._make_observation(sensors) vehicle_pos = self.vehicle.state['pos'] vehicle_pos = Point(*vehicle_pos) self.last_spine_proj = self._spine_project_vehicle(vehicle_pos) return self.observation def advance(self): self.bng.step(self.steps, wait=False) def observe(self): sensors = self.bng.poll_sensors(self.vehicle) new_observation = self._make_observation(sensors) return new_observation, sensors def step(self, action): action = [*np.clip(action, -1, 1), action[0], action[1]] action = [float(v) for v in action] self.episode_steps += 1 self._make_commands(action) self.advance() new_observation, sensors = self.observe() if self.observation is not None: self.last_observation = self.observation self.observation = new_observation score, done = self._compute_reward(sensors) print((' A: {:5.2f} B: {:5.2f} ' ' S: {:5.2f} T: {:5.2f} R: {:5.2f}').format( action[2], action[3], action[0], action[1], score)) # if done: # self.bng.step(WCARaceGeometry.sps * 1) return self.observation, score, done, {}
def polygonFromCoords(c): ''' Create polygon from coordinates''' r = LinearRing(c) polygon = Polygon(r) return polygon
from vpype import LineCollection, VectorData from .utils import line_collection_contains LINE_COLLECTION_TWO_LINES = [ LineCollection([[0, 1 + 1j], [2 + 2j, 3 + 3j, 4 + 4j]]), [[0, 1 + 1j], [2 + 2j, 3 + 3j, 4 + 4j]], ([0, 1 + 1j], [2 + 2j, 3 + 3j, 4 + 4j]), ((0, 1 + 1j), (2 + 2j, 3 + 3j, 4 + 4j)), np.array([[0, 1 + 1j], [2 + 2j, 3 + 3j, 4 + 4j]]), MultiLineString([[(0, 0), (1, 1)], [(2, 2), (3, 3), (4, 4)]]), ] LINE_COLLECTION_LINESTRING_LINEARRING = [ LineString([(0, 0), (1, 1), (3, 5)]), LinearRing([(10, 10), (11, 41), (12, 12), (10, 10)]), ] EMPTY_LINE_COLLECTION = [ MultiLineString([[(0, 0), (1, 1)], [(2, 2), (3, 3), (4, 4)]]).intersection( Point(50, 50).buffer(1.0) ), # this is an empty geometry LineString([(0, 0), (1, 1), (3, 5)]).intersection(Point(50, 50).buffer(1.0)), LinearRing([(10, 10), (11, 41), (12, 12), (10, 10)]).intersection(Point(0, 0).buffer(1)), ] def _line_set(lc: Iterable[Sequence[complex]]) -> Set[Tuple[complex, ...]]: return {tuple(line if abs(line[0]) > abs(line[-1]) else reversed(line)) for line in lc}
def compute(v, P): """ Compute the visible part of P from v """ #print("Previsible polygon: %s"%(P,)) # Used for visilibity library epsilon = 0.01 #Using the visilibity library, define the reflex vertex observer = vis.Point(*v[1]) # To put into standard form, do this if not LinearRing(P[0]).is_ccw: ext = P[0][::-1] else: ext = P[0] x_min_idx, x_min = min(enumerate(ext), key=lambda x: x[1]) ext = ext[x_min_idx:] + ext[:x_min_idx] #print x_min_idx, x_min # Define the walls of intersection in Visilibity domain wall_points = [] for point in ext: wall_points.append(vis.Point(*point)) #print 'Walls in standard form : ',vis.Polygon(wall_points).is_in_standard_form() #for i in range(len(vis_intersection_wall_points)): #print vis_intersection_wall_points[i].x(), vis_intersection_wall_points[i].y() #print point.x(), point.y() # Define the holes of intersection in Visilibity domain holes = [] for interior in P[1]: hole_points = [] for point in interior: hole_points.append(vis.Point(*point)) holes.append(hole_points) #print 'Hole in standard form : ',vis.Polygon(hole_points).is_in_standard_form() # Construct a convinient list env = [] env.append(vis.Polygon(wall_points)) for hole in holes: env.append(vis.Polygon(hole)) # Construct the whole envrionemt in Visilibity domain env = vis.Environment(env) # Construct the visible polygon observer.snap_to_boundary_of(env, epsilon) observer.snap_to_vertices_of(env, epsilon) vis_free_space = vis.Visibility_Polygon(observer, env, epsilon) point_x, point_y = save_print(vis_free_space) point_x.append(vis_free_space[0].x()) point_y.append(vis_free_space[0].y()) return point_x, point_y
def test_interiors(self): square_series = GeoSeries(self.nested_squares) exp_interiors = GeoSeries([LinearRing(self.inner_sq.boundary)]) for expected, computed in zip(exp_interiors, square_series.interiors): assert computed[0].equals(expected)
def combine_chains(P, theta): """ Combine the simple chains to form one non simple chain. This is to allow decomposing cuts. The combination cuts are oriented at theta. """ theta = 0 modified_edges = [] P = rotation.rotate_polygon(P, -theta) minx, miny, maxx, maxy = Polygon(*P).bounds chains = [] for hole in P[1]: chains.append(hole) chains.append(P[0]) # Loop over the whole chain dict except the last case for i in range(len(chains) - 1): chain = chains[i] R = reflex.find_reflex_vertices([chain, []]) for v in R: #print("Reflex v: %s"%(v,)) hyperplane = LineString([(v[1][0], maxy), (v[1][0], miny)]) #print("Hyperplane: %s"%hyperplane) # Initialize up and down arrays up = [] down = [] for j in range(i, len(chains)): #print("Chain tested with hyperplane: %s"%chains[j]) intersection = hyperplane.intersection(LinearRing(chains[j])) # Empty intersection means other holes weren't aligned with the # hyperplane therefore no intersection is expected #print("Isection Type: %s"%intersection.geom_type) if intersection.is_empty: continue #print("Intersection: %s"%intersection) points = get_points_from_intersection(intersection) #print("Points from intersection: %s"%points) # Insert intersections into respective arrays for x, y in points: if y > v[1][1]: up.append(((x, y), j)) continue elif y < v[1][1]: down.append(((x, y), j)) continue elif y == v[1][1]: up.append(((x, y), j)) down.append(((x, y), j)) continue # Sort the up and down arrays up = sorted(up, key=lambda elem: elem[0][1]) down = sorted(down, key=lambda elem: elem[0][1]) #print("Up: %s"%up) #print("Down: %s"%down) # If closest points is hole itself, go to the next reflex vertex if (up[1][1] == i) and (down[-2][1] == i): continue if up[1][1] == i: cut_parameters = down[-2] break if down[-2][1] == i: cut_parameters = up[1] break cut_parameters = up[1] break # Maybe need to choose smartly #print("Cut Param: %s"%(cut_parameters,)) #print("Cutting from: %s to %s"%(v, cut_parameters)) orig_chain = LineString(chain + [chain[0]]) dest_chain = LineString(chains[cut_parameters[1]] + [chains[cut_parameters[1]][0]]) #print("Orig chain: %s"%orig_chain) #print("Dest chain: %s"%dest_chain) distance_to_v = orig_chain.project(Point(v[1])) distance_to_w = dest_chain.project(Point(cut_parameters[0])) #print("Dist_v: %2f, Dist_w: %2f"%(distance_to_v, distance_to_w)) #print("Orig_l: %2f, Dist_l: %2f"%(orig_chain.length, dest_chain.length)) if distance_to_v == 0: orig_chain_1 = orig_chain.coords[:] orig_chain_2 = [] else: orig_chain_1, orig_chain_2 = cut(orig_chain, distance_to_v) orig_chain_1 = orig_chain_1.coords[:] orig_chain_2 = orig_chain_2.coords[:] if distance_to_w == 0: dest_chain_1 = [] dest_chain_2 = dest_chain.coords[:] else: dest_chain_1, dest_chain_2 = cut(dest_chain, distance_to_w) dest_chain_1 = dest_chain_1.coords[:] dest_chain_2 = dest_chain_2.coords[:-1] #print cut(dest_chain, distance_to_w) #if LinearRing(dest_chain).is_ccw: #print("Orig chain1: %s"%(orig_chain_1,)) #print("Orig chain2: %s"%(orig_chain_2,)) #print("Dest chain1: %s"%(dest_chain_1,)) #print("Dest chain2: %s"%(dest_chain_2,)) final_chain = orig_chain_1 + dest_chain_2 + dest_chain_1 + orig_chain_2 # final_chain = dest_chain_1[:]+\ # orig_chain_2[:-1]+\ # orig_chain_1[:]+\ # dest_chain_2[:-1] # Now modify the chains array accoridngly to propagate the fusion method if cut_parameters[1] == (len(chains) - 1): chains[len(chains) - 1] = final_chain else: chains[cut_parameters[1]] = final_chain modified_edges.append( rotation.rotate_points([v[1], cut_parameters[0]], theta)) #print("Active verts: %s"%active_verts) #print("Final chain: %s"%final_chain) return rotation.rotate_polygon([chains[len(chains) - 1], []], theta), modified_edges
def create_phase_tensor_shp(self, period, ellipsize=None, target_epsg_code=4283, export_fig=False): """ create phase tensor ellipses shape file correspond to a MT period :return: (geopdf_obj, path_to_shapefile) """ if ellipsize is None: # automatically decide suitable ellipse size. ellipsize = self.stations_distances.get("Q1PERCENT") / 2 # a half or a third of the min_distance? self._logger.debug("Automatically Selected Max-Ellispse Size = %s", ellipsize) pt = self.get_phase_tensor_tippers(period) self._logger.debug("phase tensor values =: %s", pt) if len(pt) < 1: self._logger.warn("No phase tensor for the period %s for any MT station", period) return None pdf = pd.DataFrame(pt) self._logger.debug(pdf['period']) mt_locations = [Point(xy) for xy in zip(pdf['lon'], pdf['lat'])] geopdf = gpd.GeoDataFrame(pdf, crs=self.orig_crs, geometry=mt_locations) # points to trace out the polygon-ellipse theta = np.arange(0, 2 * np.pi, np.pi / 30.) azimuth = -np.deg2rad(geopdf['azimuth']) scaling = ellipsize / geopdf['phi_max'] width = geopdf['phi_max'] * scaling height = geopdf['phi_min'] * scaling x0 = geopdf['lon'] y0 = geopdf['lat'] # Find invalid ellipses bad_min = np.where(np.logical_or(geopdf['phi_min'] == 0, geopdf['phi_min'] > 100))[0] bad_max = np.where(np.logical_or(geopdf['phi_max'] == 0, geopdf['phi_max'] > 100))[0] dot = 0.0000001 * ellipsize height[bad_min] = dot height[bad_max] = dot width[bad_min] = dot width[bad_max] = dot # apply formula to generate ellipses ellipse_list = [] for i in range(0, len(azimuth)): x = x0[i] + height[i] * np.cos(theta) * np.cos(azimuth[i]) - \ width[i] * np.sin(theta) * np.sin(azimuth[i]) y = y0[i] + height[i] * np.cos(theta) * np.sin(azimuth[i]) + \ width[i] * np.sin(theta) * np.cos(azimuth[i]) polyg = Polygon(LinearRing([xy for xy in zip(x, y)])) # print polyg # an ellispe ellipse_list.append(polyg) geopdf = gpd.GeoDataFrame(geopdf, crs=self.orig_crs, geometry=ellipse_list) if target_epsg_code is None: self._logger.info("The orginal Geopandas Dataframe CRS: %s", geopdf.crs) # {'init': 'epsg:4283', 'no_defs': True} # raise Exception("Must provide a target_epsg_code") target_epsg_code = geopdf.crs['init'][5:] else: geopdf.to_crs(epsg=target_epsg_code, inplace=True) # world = world.to_crs({'init': 'epsg:3395'}) # world.to_crs(epsg=3395) would also work path2shp = \ self._export_shapefiles(geopdf, 'Phase_Tensor', target_epsg_code, period, export_fig) return (geopdf, path2shp)
def polygons_to_geom_dicts(polygons, skip_invalid=True): """ Converts a Polygons element into a list of geometry dictionaries, preserving all value dimensions. For array conversion the following conventions are applied: * Any nan separated array are converted into a MultiPolygon * Any array without nans is converted to a Polygon * If there are holes associated with a nan separated array the holes are assigned to the polygons by testing for an intersection * If any single array does not have at least three coordinates it is skipped by default * If skip_invalid=False and an array has less than three coordinates it will be converted to a LineString """ interface = polygons.interface.datatype if interface == 'geodataframe': return [row.to_dict() for _, row in polygons.data.iterrows()] elif interface == 'geom_dictionary': return [polygons.data] elif interface == 'multitabular' and all(isinstance(p, dict) and 'geometry' in p for p in polygons.data): return polygons.data polys = [] xdim, ydim = polygons.kdims has_holes = polygons.has_holes holes = polygons.holes() if has_holes else None for i, polygon in enumerate(polygons.split(datatype='columns')): array = np.column_stack([polygon.pop(xdim.name), polygon.pop(ydim.name)]) splits = np.where(np.isnan(array[:, :2].astype('float')).sum(axis=1))[0] arrays = np.split(array, splits+1) if len(splits) else [array] invalid = False subpolys = [] subholes = None if has_holes: subholes = [[LinearRing(h) for h in hs] for hs in holes[i]] for j, arr in enumerate(arrays): if j != (len(arrays)-1): arr = arr[:-1] # Drop nan if len(arr) == 0: continue elif len(arr) == 1: if skip_invalid: continue poly = Point(arr[0]) invalid = True elif len(arr) == 2: if skip_invalid: continue poly = LineString(arr) invalid = True elif not len(splits): poly = Polygon(arr, (subholes[j] if has_holes else [])) else: poly = Polygon(arr) hs = [h for h in subholes[j]] if has_holes else [] poly = Polygon(poly.exterior, holes=hs) subpolys.append(poly) if invalid: polys += [dict(polygon, geometry=sp) for sp in subpolys] continue elif len(subpolys) == 1: geom = subpolys[0] elif subpolys: geom = MultiPolygon(subpolys) else: continue polygon['geometry'] = geom polys.append(polygon) return polys
def test_any_vector_to_fc_raises_with_not_accepted(): ring = LinearRing([(0, 0), (1, 1), (1, 0)]) with pytest.raises(ValueError): any_vector_to_fc(ring)
def load_data(self): width_scale = 1.25 height_scale = 1.25 if self.projection == "EPSG:32661": # north pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) if self.centroid[0] > 80 or near_pole or covers_pole: self.plot_projection = ccrs.Stereographic( central_latitude=self.centroid[0], central_longitude=self.centroid[1], ) width_scale = 1.5 else: self.plot_projection = ccrs.LambertConformal( central_latitude=self.centroid[0], central_longitude=self.centroid[1], ) elif self.projection == "EPSG:3031": # south pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) # is centerered close to the south pole if ((self.centroid[0] < -80 or self.bounds[1] < -80 or self.bounds[3] < -80) or covers_pole) or near_pole: self.plot_projection = ccrs.Stereographic( central_latitude=self.centroid[0], central_longitude=self.centroid[1], ) width_scale = 1.5 else: self.plot_projection = ccrs.LambertConformal( central_latitude=self.centroid[0], central_longitude=self.centroid[1], ) elif abs(self.centroid[1] - self.bounds[1]) > 90: if abs(self.bounds[3] - self.bounds[1]) > 360: raise ClientError( gettext( "You have requested an area that exceeds the width \ of the world. Thinking big is good but plots need to \ be less than 360 deg wide.")) self.plot_projection = ccrs.Mercator( central_longitude=self.centroid[1]) else: self.plot_projection = ccrs.LambertConformal( central_latitude=self.centroid[0], central_longitude=self.centroid[1]) proj_bounds = self.plot_projection.transform_points( self.pc_projection, np.array([self.bounds[1], self.bounds[3]]), np.array([self.bounds[0], self.bounds[2]]), ) proj_size = np.diff(proj_bounds, axis=0) width = proj_size[0][0] * width_scale height = proj_size[0][1] * height_scale aspect_ratio = height / width if aspect_ratio < 1: gridx = 500 gridy = int(500 * aspect_ratio) else: gridy = 500 gridx = int(500 / aspect_ratio) self.plot_res = basemap.get_resolution(height, width) x_grid, y_grid, self.plot_extent = cimg_transform.mesh_projection( self.plot_projection, gridx, gridy, x_extents=(-width / 2, width / 2), y_extents=(-height / 2, height / 2), ) latlon_grid = self.pc_projection.transform_points( self.plot_projection, x_grid, y_grid) self.longitude = latlon_grid[:, :, 0] self.latitude = latlon_grid[:, :, 1] variables_to_load = self.variables[:] # we don't want to change self,variables so copy it if self.__load_quiver(): variables_to_load.append(self.quiver["variable"]) with open_dataset(self.dataset_config, variable=variables_to_load, timestamp=self.time) as dataset: self.variable_unit = self.get_variable_units( dataset, self.variables)[0] self.variable_name = self.get_variable_names( dataset, self.variables)[0] if self.cmap is None: self.cmap = colormap.find_colormap(self.variable_name) if self.depth == "bottom": depth_value_map = "Bottom" else: self.depth = np.clip(int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] depth_value_map = depth_value data = [] var = dataset.variables[self.variables[0]] if self.filetype in ["csv", "odv", "txt"]: d, depth_value_map = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.variables[0], self.interp, self.radius, self.neighbours, return_depth=True, ) else: d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.variables[0], self.interp, self.radius, self.neighbours, ) data.append(d) if self.filetype not in ["csv", "odv", "txt"]: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == "bottom": self.depth_label = " at Bottom" else: self.depth_label = (" at " + str(int(np.round(depth_value_map))) + " m") self.data = data[0] quiver_data = [] # Store the quiver data on the same grid as the main variable. This # will only be used for CSV export. quiver_data_fullgrid = [] if self.__load_quiver(): var = dataset.variables[self.quiver["variable"]] quiver_unit = self.dataset_config.variable[var].unit quiver_name = self.dataset_config.variable[var].name quiver_x_var = self.dataset_config.variable[ var].east_vector_component quiver_y_var = self.dataset_config.variable[ var].north_vector_component quiver_x, quiver_y, _ = cimg_transform.mesh_projection( self.plot_projection, 50, 50, self.plot_extent[:2], self.plot_extent[2:], ) quiver_coords = self.pc_projection.transform_points( self.plot_projection, quiver_x, quiver_y) quiver_lon = quiver_coords[:, :, 0] quiver_lat = quiver_coords[:, :, 1] x_vals = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, quiver_x_var, self.interp, self.radius, self.neighbours, ) quiver_data.append(x_vals) y_vals = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, quiver_y_var, self.interp, self.radius, self.neighbours, ) quiver_data.append(y_vals) mag_data = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, self.quiver["variable"], self.interp, self.radius, self.neighbours, ) self.quiver_magnitude = mag_data # Get the quiver data on the same grid as the main # variable. x_vals = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, quiver_x_var, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(x_vals) y_vals = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, quiver_y_var, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(y_vals) self.quiver_name = self.get_variable_names( dataset, [self.quiver["variable"]])[0] self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data self.quiver_data_fullgrid = quiver_data_fullgrid if all([ dataset.variables[v].is_surface_only() for v in variables_to_load ]): self.depth = 0 contour_data = [] if (self.contour is not None and self.contour["variable"] != "" and self.contour["variable"] != "none"): d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour["variable"], self.interp, self.radius, self.neighbours, ) vc = self.dataset_config.variable[self.contour["variable"]] contour_unit = vc.unit contour_name = vc.name contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.nc_data.timestamp_to_iso_8601(self.time) if self.compare: self.variable_name += " Difference" compare_config = DatasetConfig(self.compare["dataset"]) with open_dataset( compare_config, variable=self.compare["variables"], timestamp=self.compare["time"], ) as dataset: data = [] for v in self.compare["variables"]: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.compare["depth"], self.compare["time"], v, self.interp, self.radius, self.neighbours, ) data.append(d) data = data[0] self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry(self.latitude, self.longitude, blur=2) if self.depth != "bottom" and self.depth != 0: if quiver_data: quiver_bathymetry = overlays.bathymetry(quiver_lat, quiver_lon) self.data[np.where( self.bathymetry < depth_value_map)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value_map)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data, True, "h", 1.25).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans(self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ["csv", "odv", "txt", "geotiff"]: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a["polygons"]] innerrings = [LinearRing(p) for p in a["innerrings"]] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [ Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel()) ] indicies = [] for a in area_polys: indicies.append( np.where( list(map(lambda p, poly=a: poly.contains(p), points)))[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value_map = depth_value_map
''' Find coordinate of Closest Point on Shapely Polygon ''' from shapely.geometry import Point from shapely.geometry import Polygon from shapely.geometry import LinearRing point = Point(0.0, 0.0) poly = Polygon([(-1, 1), (2, 1), (2, 2), (-1, 2)]) # Polygon exterior ring exterior = LinearRing(poly.exterior.coords) dist = exterior.project(point) closest_point = exterior.interpolate(dist) print(closest_point)
def getClosestPointPoly(poly, point): pol_ext = LinearRing(poly.exterior.coords) d = pol_ext.project(point) p = pol_ext.interpolate(d) return list(p.coords)[0]
def removebadfacetsshow(self, base, doverh=.1): """ remove the facets that cannot support stable placements :param: doverh: d is the distance of mproj to supportfacet boundary, h is the height of com when fh>dmg, the object tends to fall over. setting doverh to 0.033 means when f>0.1mg, the object is judged to be unstable :return: author: weiwei date: 20161213 """ plotoffsetfp = 10 # print self.counter if self.counter < len(self.ocfacets): i = self.counter # for i in range(len(self.ocfacets)): geom = pg.packpandageom(self.objtrimeshconv.vertices, self.objtrimeshconv.face_normals[self.ocfacets[i]], self.objtrimeshconv.faces[self.ocfacets[i]]) geombullnode = cd.genCollisionMeshGeom(geom) self.bulletworldray.attachRigidBody(geombullnode) pFrom = Point3(self.objcom[0], self.objcom[1], self.objcom[2]) pTo = self.objcom+self.ocfacetnormals[i]*99999 pTo = Point3(pTo[0], pTo[1], pTo[2]) result = self.bulletworldray.rayTestClosest(pFrom, pTo) self.bulletworldray.removeRigidBody(geombullnode) if result.hasHit(): hitpos = result.getHitPos() pg.plotArrow(base.render, spos=self.objcom, epos = self.objcom+self.ocfacetnormals[i], length=100) facetinterpnt = np.array([hitpos[0],hitpos[1],hitpos[2]]) facetnormal = np.array(self.ocfacetnormals[i]) bdverts3d, bdverts2d, facetmat4 = pg.facetboundary(self.objtrimeshconv, self.ocfacets[i], facetinterpnt, facetnormal) for j in range(len(bdverts3d)-1): spos = bdverts3d[j] epos = bdverts3d[j+1] pg.plotStick(base.render, spos, epos, thickness = 1, rgba=[.5,.5,.5,1]) facetp = Polygon(bdverts2d) facetinterpnt2d = rm.transformmat4(facetmat4, facetinterpnt)[:2] apntpnt = Point(facetinterpnt2d[0], facetinterpnt2d[1]) dist2p = apntpnt.distance(facetp.exterior) dist2c = np.linalg.norm(np.array([hitpos[0],hitpos[1],hitpos[2]])-np.array([pFrom[0],pFrom[1],pFrom[2]])) if dist2p/dist2c < doverh: print "not stable" # return else: print dist2p/dist2c pol_ext = LinearRing(bdverts2d) d = pol_ext.project(apntpnt) p = pol_ext.interpolate(d) closest_point_coords = list(p.coords)[0] closep = np.array([closest_point_coords[0], closest_point_coords[1], 0]) closep3d = rm.transformmat4(rm.homoinverse(facetmat4), closep)[:3] pg.plotDumbbell(base.render, spos=facetinterpnt, epos=closep3d, thickness=1.5, rgba=[0,0,1,1]) for j in range(len(bdverts3d)-1): spos = bdverts3d[j] epos = bdverts3d[j+1] pg.plotStick(base.render, spos, epos, thickness = 1.5, rgba=[0,1,0,1]) # geomoff = pg.packpandageom(self.objtrimeshconv.vertices + # np.tile(plotoffsetfp * self.ocfacetnormals[i], # [self.objtrimeshconv.vertices.shape[0], 1]), # self.objtrimeshconv.face_normals[self.ocfacets[i]], # self.objtrimeshconv.faces[self.ocfacets[i]]) # # nodeoff = GeomNode('supportfacet') # nodeoff.addGeom(geomoff) # staroff = NodePath('supportfacet') # staroff.attachNewNode(nodeoff) # staroff.setColor(Vec4(1,0,1,1)) # staroff.setTransparency(TransparencyAttrib.MAlpha) # staroff.setTwoSided(True) # staroff.reparentTo(base.render) self.counter+=1 else: self.counter=0
# Copyright (c) 2020. JetBrains s.r.o. # Use of this source code is governed by the MIT license that can be found in the LICENSE file. import json from .geo_data import get_data_meta, get_map_data_meta from geopandas import GeoDataFrame from shapely.geometry import MultiPolygon, Polygon, LinearRing, Point, mapping from lets_plot._type_utils import _standardize_value from lets_plot.plot import ggplot, geom_polygon POINT = Point(-12.34, 56.78) POLYGON = Polygon(LinearRing([(1, 1), (1, 9), (9, 9), (9, 1)]), [ LinearRing([(2, 2), (3, 2), (3, 3), (2, 3)]), LinearRing([(4, 4), (6, 4), (6, 6), (4, 6)]) ]) MULTIPOLYGON = MultiPolygon( [POLYGON, Polygon(LinearRing([(11, 12), (13, 14), (15, 16)]))]) names = ['A', 'B', 'C'] geoms = [POINT, POLYGON, MULTIPOLYGON] EXPECTED_GDF_META = {'geodataframe': {'geometry': 'coord'}} def make_geodataframe() -> GeoDataFrame: return GeoDataFrame(data={'name': names, 'coord': geoms}, geometry='coord')
def create_hatch(polygon, interval_wish, first_offset=None, last_offset=None, horizontal=False, exact=False, holes=None): """ polygon: bounding box interval_wish: create i.e. 125mm boards, extend interval for equal spacing (rimalaudoitus) first_offset: like 50 mm. from corner (nurkkalaudat mahtuu) """ # todo actual polygon instead of a 2d bounding box? if needed #trace("polpol: ", polygon) min_x, min_y, max_x, max_y = bounding_box(polygon) coords = [] actual_interval = interval_wish # horizontal battens is completely different if horizontal: if first_offset is not None: min_y += first_offset height = abs(max_y - min_y) spacing_count = int(height / interval_wish) board_count = spacing_count + 1 y_offset = min_y # todo: something wrong with zero here for i in range(board_count): coords.extend([((min_x, y_offset), (max_x, y_offset))]) y_offset += interval_wish # last ninja last_y = max_y coords.extend([((min_x, last_y), (max_x, last_y))]) #trace("crds: ", coords) else: # vertical boards, e.g. cladding if first_offset is not None: min_x += first_offset if last_offset is not None: max_x -= last_offset # round down to nearest fitting millimeter width = abs(max_x - min_x) spacing_count = int(width / interval_wish) actual_interval = width / spacing_count board_count = spacing_count + 1 if exact: actual_interval = interval_wish x_offset = min_x # todo: something wrong with zero here for i in range(board_count): coords.extend([((x_offset, max_y), (x_offset, min_y))]) x_offset += actual_interval # turn array into Shapely object spoints = MultiLineString(coords) #trace_multiline(spoints) #trace("msl: ", spoints) wall_polygon = LinearRing([(p.x, p.y) for p in polygon]) #cladding_hatch = wall_polygon.intersection(spoints) trace("interval actual: ", actual_interval, max_x, min_x, max_y, min_y) windows = [] if holes is not None: #alt_poly = LinearRing([(p.x,p.y) for p in polygon]) for windef in holes: trace("holes: ", windef) x0, y0, dx, dy = windef.minmax_coords() rect = box(x0, y0, x0 + dx, y0 + dy) #alt_poly = alt_poly.difference(rect) windows.append(rect) #trace("alt_poly: ", alt_poly) #wall_polygon = wall_polygon.difference(rect) #spoints = wall_polygon.intersection(spoints) #alt_poly = Polygon(wall_polygon, [LinearRing(r) for r in windows]) #wall_polygon = Polygon([(p.x,p.y) for p in polygon], [r.exterior.coords for r in windows]) #trace("alt_poly: ", wall_polygon) pps = [] # convert back to 3d points for linestr in spoints.geoms: #for linestr in cladding_hatch.geoms: source = linestr.coords # check isect coll = linestr.intersection(wall_polygon) #trace("col: ", coll, source) #try: if isinstance(coll, Point): coll = [source] if isinstance(coll, LineString): # and 2 == len(coll): coll = [coll.coords] if isinstance(coll, MultiLineString) or isinstance( coll, MultiPoint): # and 2 == len(coll): #trace("multi") coll = [a.coords for a in coll.geoms] #except: # pass #trace("intersect: ", coll) #coll.sort(key=lambda tup: tup[1]) # i=y, sorts in place linepts = [] for coord in coll: for (x, y) in coord: #trace("begin: ", x, " end: ", y) #pps.append(Point3(*begin[0], *begin[1], 0))#, Point3(*end[0], *end[1], 0)) linepts.append(Point3(x, y, 0)) #trace(begin, end) #pps.push([Point3(x, y, 0), Point #if 2 == len(linepts): # pps.append([x.Clone() for x in linepts]) # trace("linepts: ", linepts) # linepts = [] linepts.sort(key=lambda p: p.y) # sort y pairs = [] for point in linepts: pairs.append(point) if 2 == len(pairs): pps.append([x.Clone() for x in pairs]) #trace("pairs: ", pairs) pairs = [] # sort pairs by rising x coord, to get e.g. rimalaudoitus in between pps.sort(key=lambda tup: tup[1].x) # sorts in place #trace("pps: ", pps[0][0]) return pps
from camlib import * from shapely.geometry import LineString, LinearRing s = FlatCAMRTreeStorage() geoms = [ LinearRing(((0.5699056603773586, 0.7216037735849057), (0.9885849056603774, 0.7216037735849057), (0.9885849056603774, 0.6689622641509434), (0.5699056603773586, 0.6689622641509434), (0.5699056603773586, 0.7216037735849057))), LineString(((0.8684952830188680, 0.6952830188679245), (0.8680655198743615, 0.6865349890935113), (0.8667803692948564, 0.6778712076279851), (0.8646522079829676, 0.6693751114229638), (0.8645044888670096, 0.6689622641509434))), LineString(((0.9874952830188680, 0.6952830188679245), (0.9864925023483531, 0.6748709493942936), (0.9856160316877274, 0.6689622641509434))), ] for geo in geoms: s.insert(geo) current_pt = (0, 0) pt, geo = s.nearest(current_pt) while geo is not None: print pt, geo print "OBJECTS BEFORE:", s.objects #geo.coords = list(geo.coords[::-1])
def load_data(self): distance = VincentyDistance() height = distance.measure( (self.bounds[0], self.centroid[1]), (self.bounds[2], self.centroid[1])) * 1000 * 1.25 width = distance.measure( (self.centroid[0], self.bounds[1]), (self.centroid[0], self.bounds[3])) * 1000 * 1.25 if self.projection == 'EPSG:32661': # north pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) if self.centroid[0] > 80 or near_pole or covers_pole: self.basemap = basemap.load_map( 'npstere', self.centroid, height, width, min(self.bounds[0], self.bounds[2])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) elif self.projection == 'EPSG:3031': # south pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) if ((self.centroid[0] < -80 or self.bounds[1] < -80 or self.bounds[3] < -80) or covers_pole ) or near_pole: # is centerered close to the south pole self.basemap = basemap.load_map( 'spstere', self.centroid, height, width, max(self.bounds[0], self.bounds[2])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) elif abs(self.centroid[1] - self.bounds[1]) > 90: height_bounds = [self.bounds[0], self.bounds[2]] width_bounds = [self.bounds[1], self.bounds[3]] height_buffer = (abs(height_bounds[1] - height_bounds[0])) * 0.1 width_buffer = (abs(width_bounds[0] - width_bounds[1])) * 0.1 if abs(width_bounds[1] - width_bounds[0]) > 360: raise ClientError( gettext( "You have requested an area that exceeds the width of the world. \ Thinking big is good but plots need to be less than 360 deg wide." )) if height_bounds[1] < 0: height_bounds[1] = height_bounds[1] + height_buffer else: height_bounds[1] = height_bounds[1] + height_buffer if height_bounds[0] < 0: height_bounds[0] = height_bounds[0] - height_buffer else: height_bounds[0] = height_bounds[0] - height_buffer new_width_bounds = [] new_width_bounds.append(width_bounds[0] - width_buffer) new_width_bounds.append(width_bounds[1] + width_buffer) if abs(new_width_bounds[1] - new_width_bounds[0]) > 360: width_buffer = np.floor( (360 - abs(width_bounds[1] - width_bounds[0])) / 2) new_width_bounds[0] = width_bounds[0] - width_buffer new_width_bounds[1] = width_bounds[1] + width_buffer if new_width_bounds[0] < -360: new_width_bounds[0] = -360 if new_width_bounds[1] > 720: new_width_bounds[1] = 720 self.basemap = basemap.load_map( 'merc', self.centroid, (height_bounds[0], height_bounds[1]), (new_width_bounds[0], new_width_bounds[1])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) if self.basemap.aspect < 1: gridx = 500 gridy = int(500 * self.basemap.aspect) else: gridy = 500 gridx = int(500 / self.basemap.aspect) self.longitude, self.latitude = self.basemap.makegrid(gridx, gridy) with open_dataset(get_dataset_url(self.dataset_name)) as dataset: if self.time < 0: self.time += len(dataset.timestamps) self.time = np.clip(self.time, 0, len(dataset.timestamps) - 1) self.variable_unit = self.get_variable_units( dataset, self.variables)[0] self.variable_name = self.get_variable_names( dataset, self.variables)[0] scale_factor = self.get_variable_scale_factors( dataset, self.variables)[0] if self.cmap is None: if len(self.variables) == 1: self.cmap = colormap.find_colormap(self.variable_name) else: self.cmap = colormap.colormaps.get('speed') if len(self.variables) == 2: self.variable_name = self.vector_name(self.variable_name) if self.depth == 'bottom': depth_value = 'Bottom' else: self.depth = np.clip(int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] data = [] allvars = [] for v in self.variables: var = dataset.variables[v] allvars.append(v) if self.filetype in ['csv', 'odv', 'txt']: d, depth_value = dataset.get_area(np.array( [self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, return_depth=True) else: d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours) d = np.multiply(d, scale_factor) self.variable_unit, d = self.kelvin_to_celsius( self.variable_unit, d) data.append(d) if self.filetype not in ['csv', 'odv', 'txt']: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == 'bottom': self.depth_label = " at Bottom" else: self.depth_label = " at " + \ str(int(np.round(depth_value))) + " m" if len(data) == 2: data[0] = np.sqrt(data[0]**2 + data[1]**2) self.data = data[0] quiver_data = [] # Store the quiver data on the same grid as the main variable. This # will only be used for CSV export. quiver_data_fullgrid = [] if self.quiver is not None and \ self.quiver['variable'] != '' and \ self.quiver['variable'] != 'none': for v in self.quiver['variable'].split(','): allvars.append(v) var = dataset.variables[v] quiver_unit = get_variable_unit(self.dataset_name, var) quiver_name = get_variable_name(self.dataset_name, var) quiver_lon, quiver_lat = self.basemap.makegrid(50, 50) d = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, ) quiver_data.append(d) # Get the quiver data on the same grid as the main # variable. d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(d) self.quiver_name = self.vector_name(quiver_name) self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data self.quiver_data_fullgrid = quiver_data_fullgrid if all( [len(dataset.variables[v].dimensions) == 3 for v in allvars]): self.depth = 0 contour_data = [] if self.contour is not None and \ self.contour['variable'] != '' and \ self.contour['variable'] != 'none': d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour['variable'], self.interp, self.radius, self.neighbours, ) contour_unit = get_variable_unit( self.dataset_name, dataset.variables[self.contour['variable']]) contour_name = get_variable_name( self.dataset_name, dataset.variables[self.contour['variable']]) contour_factor = get_variable_scale_factor( self.dataset_name, dataset.variables[self.contour['variable']]) contour_unit, d = self.kelvin_to_celsius(contour_unit, d) d = np.multiply(d, contour_factor) contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.timestamps[self.time] if self.compare: self.variable_name += " Difference" with open_dataset(get_dataset_url( self.compare['dataset'])) as dataset: data = [] for v in self.compare['variables']: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.compare['depth'], self.compare['time'], v, self.interp, self.radius, self.neighbours, ) data.append(d) if len(data) == 2: data = np.sqrt(data[0]**2 + data[1]**2) else: data = data[0] u, data = self.kelvin_to_celsius( dataset.variables[self.compare['variables'][0]].unit, data) self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry(self.basemap, self.latitude, self.longitude, blur=2) if self.depth != 'bottom' and self.depth != 0: if len(quiver_data) > 0: quiver_bathymetry = overlays.bathymetry( self.basemap, quiver_lat, quiver_lon) self.data[np.where(self.bathymetry < depth_value)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data, True, 'h', 1.25).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans(self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ['csv', 'odv', 'txt', 'geotiff']: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a['polygons']] innerrings = [LinearRing(p) for p in a['innerrings']] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [ Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel()) ] indicies = [] for a in area_polys: indicies.append( np.where( list(map(lambda p, poly=a: poly.contains(p), points)))[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value = depth_value
def test_fc_to_query_geometry_raises_with_not_accepted(): ring = LinearRing([(0, 0), (1, 1), (1, 0)]) with pytest.raises(ValueError): fc_to_query_geometry(ring, geometry_operation="bbox")
def simulation(self): """explain""" for run in range(self.variables.runs): print("run nr {0} running".format(str(run + 1))) """get indexes for all roles for specific run""" agenda_setter_index = np.where( self.voter_role_array[run, :] == 2)[0] veto_player_index = np.where(self.voter_role_array[run, :] == 1)[0] normal_player_index = np.where( self.voter_role_array[run, :] == 0)[0] """calculate run radius for all voters and update radius array""" self.voter_radius_array[ run, agenda_setter_index] = self.determine_distance( self.voter_position_array[agenda_setter_index, run], self.statusquo[[run]], self.variables.distance_type) if veto_player_index.any(): self.voter_radius_array[ run, veto_player_index] = self.determine_distance( self.statusquo[[run]], self.voter_position_array[veto_player_index, run], self.variables.distance_type) if normal_player_index.any(): self.voter_radius_array[ run, normal_player_index] = self.determine_distance( self.statusquo[[run]], self.voter_position_array[normal_player_index, run], self.variables.distance_type) """check if agenda setter position == status quo position, in which case the outcome is predetermined""" if (self.voter_position_array[agenda_setter_index, run] == self.statusquo[run]).all(): self.outcomes[run] = self.statusquo[run] self.total_pyth_distance[run] = 0 self.total_manh_distance[run] = 0 self.dimension_distance[run] = [ 0 for _ in range(self.variables.dimensions) ] if self.variables.runs > 1 and run != self.variables.runs - 1: self.alter_statusquo(run) self.alter_player_preferences(run) continue """determine possible coalitions given a selected majority rule -- coalitions necessarily include veto players and agenda setter""" possible_coalitions = self.determine_coalitions( agenda_setter_index, veto_player_index, normal_player_index) # TODO from coalition grid search to function possible_outcomes = [] """grid search""" if self.variables.method == "grid" or self.variables.method == "random grid": """grid index to make grid a square around agenda setter radius""" grid_index = [ [ self.voter_position_array[agenda_setter_index, run].item(dim) - self.voter_radius_array[run, agenda_setter_index].item(0) for dim in range(self.variables.dimensions) ], [ self.voter_position_array[agenda_setter_index, run].item(dim) + self.voter_radius_array[run, agenda_setter_index].item(0) for dim in range(self.variables.dimensions) ] ] if self.variables.method == "grid": point_grid = self.grid_paint(*grid_index, self.variables.breaks, self.break_decimal) else: point_grid = self.random_grid_paint(*grid_index) """exclude points that are outside of agenda setter and veto player winsets""" point_grid = self.grid_points_in_winset( point_grid, self.statusquo[[run]], self.voter_position_array[agenda_setter_index, run]) point_grid = self.grid_points_in_winset( point_grid, self.statusquo[[run]], self.voter_position_array[veto_player_index, run]) if possible_coalitions: """select outcomes for all coalitions""" for coalition in possible_coalitions: points_in_winset = self.grid_points_in_winset( point_grid, self.statusquo[[run]], np.vstack( [self.voter_position_array[coalition, run]])) possible_outcome = self.grid_closest_to_agenda_setter( points_in_selection=points_in_winset, as_index=agenda_setter_index, run=run) possible_outcomes.append(possible_outcome) else: possible_outcomes.append( self.grid_closest_to_agenda_setter( point_grid, agenda_setter_index, run)) if len(possible_outcomes) > 1: possible_outcomes = np.vstack( [item for item in possible_outcomes]) """select outcome closest to agenda setter""" outcome = self.grid_closest_to_agenda_setter( possible_outcomes, agenda_setter_index, run) self.outcomes[run] = outcome else: self.outcomes[run] = possible_outcomes[0] else: statusquo_point = Point(self.statusquo[run]) voter_points = [ Point(position) for position in self.voter_position_array[:, run, :] ] voter_circles = [ point.buffer(point.distance(statusquo_point)) for point in voter_points ] winsets = [] if possible_coalitions: for coalition in possible_coalitions: intersection = voter_circles[ agenda_setter_index.item()] # intersection = [voter_circles[index] for index in agendaSetterIndex][0] for voter in coalition + veto_player_index.tolist(): # intersection = intersection.intersection(voter_circles[voter]) intersection = intersection.intersection( [voter_circles[index] for index in [voter]][0]) winsets.append(intersection) else: intersection = voter_circles[agenda_setter_index.item()] for voter in veto_player_index: # intersection = intersection.intersection(voter_circles[voter]) intersection = intersection.intersection( [voter_circles[index] for index in [voter]][0]) winsets.append(intersection) agenda_setter_overlap = False closest_points = [] for i, winset in enumerate(winsets): if winset.area > 0: if winset.contains( voter_points[agenda_setter_index[0]]): closest_points.append( voter_points[agenda_setter_index[0]]) min_index = i agenda_setter_overlap = True break pol_ext = LinearRing(winset.exterior.coords) #d = polExt.project(voter_points[agendaSetterIndex]) d = pol_ext.project([ voter_points[index] for index in agenda_setter_index ][0]) p = pol_ext.interpolate(d) closest_point = p.coords[0] closest_points.append(closest_point) else: closest_points.append(self.statusquo[run].tolist()) if agenda_setter_overlap: self.outcomes[run] = closest_points[0] else: closest_points_distances = [ self.determine_distance( self.voter_position_array[agenda_setter_index, run], np.array([point])) for point in closest_points ] min_index = np.argmin(closest_points_distances) self.outcomes[run] = closest_points[min_index] if self.variables.visualize: if np.any(self.outcomes[run] != self.statusquo[run] ): #any vs all ? self.winset_patches.append( PatchCollection( [Polygon(winsets[min_index].exterior)], facecolor="red", linewidth=.5, alpha=.7)) else: self.winset_patches.append(None) self.winset_rads.append(None) self.winset_centroids.append(None) """determine distances travelled in run""" self.total_pyth_distance[run] = self.determine_distance( self.outcomes[[run]], self.statusquo[[run]]) self.total_manh_distance[run] = self.determine_distance( self.outcomes[[run]], self.statusquo[[run]], "cityblock") self.dimension_distance[run] = np.column_stack([ self.determine_distance(self.statusquo[[run]][None, :, dim], self.outcomes[[run]][None, :, dim], self.variables.distance_type) for dim in range(self.variables.dimensions) ]) """alter status quo and preferences""" if self.variables.runs > 1 and run != self.variables.runs - 1: self.alter_statusquo(run) # original passed on "self.outcomes[[run]])" if not self.custom_position_array_set: self.alter_player_preferences(run) # if self.Variables.visualize: # self.visualizeResults() if self.variables.save.lower() == 'yes': self.save_results() if any([ self.variables.random_veto_player, self.variables.random_agenda_setter ]): self.save_role_array()
# %% pnt = (2, 0, 0.5) start = (1, 0, 2) end = (4.5, 0, 0.5) # %% pnt2line(pnt=pnt, start=start, end=end) # %% from shapely.geometry import LinearRing, LineString, Polygon # %% r0 = [(0, 0), (1, 1), (1, 2)] r1 = LineString([(0, 0), (1, 1), (1, 2), (0, 0)]) r2 = LinearRing([(0, 0), (1, 1), (1, 2)]) r3 = LineString(r0) # %% s0 = Polygon(r0) s1 = Polygon(r1) s2 = Polygon(r2) s3 = Polygon(r3) # %% s.area # %% test = [(803676.680268817, 9120464.63376052), (803707.19531476, 9120486.99913016), (803738.291596794, 9120486.99913016),
# -*- coding: utf-8 -*- import os #yibande from shapely.geometry import Point, LineString, LinearRing, MultiPolygon Point(0,0).has_z Point(0,0,0).has_z LinearRing([(1,0),(1,1),(0,0)]).is_ccw ring= LinearRing([(0,0),(1,1),(1,0)]) ring.is_ccw ring.coords = list(ring.coords)[::-1] ring.is_ccw Point().is_empty Point(0,0).is_empty from operator import attrgetter empties = filter(attrgetter('is_empty'),[Point(),Point(0,0), Point(1,2,3)]) # len(empties) LineString([(0,0),(1,1),(1,-1)]).is_ring LinearRing([(0,0),(1,1),(1,-1)]).is_ring LineString([(0,0),(1,1),(1,-1),(0,1)]).is_simple MultiPolygon([Point(0,0).buffer(2.0),Point(1,1).buffer(2.0)]).is_valid from functools import wraps def validata(func):