def initialize_shapely_geoms(start, finish, obstacles): start = Point(start) finish = Point(finish) obstacles_init = [] obstacles_shapely = [] plt.figure(figsize=(10, 10)) plt.axis('equal') line = LineString([start, finish]) for ob in obstacles: ob.append(ob[0]) obstacles_init.append(np.array(ob)) shapely_polygon = Polygon(ob) obstacles_shapely.append({ 'distance_from_start': shapely_polygon.distance(start), 'distance_to_finish': shapely_polygon.distance(finish), 'obstacle': shapely_polygon }) x, y = zip(*ob) plt.plot(x, y, c='red') obstacles_shapely = sorted(obstacles_shapely, key=lambda k: (-k['distance_to_finish'])) return start, finish, line, obstacles_shapely, obstacles_init
def filter(self, bbox, mode="exact", min_dist=5): """ Filter to obtain words located in or near a bounding box. Bounding box is a dict with keys hmin,hmax,wmin,wmax Returns: [list] -- [Word instances] """ p1 = Polygon([ (bbox["hmin"], bbox["wmin"]), (bbox["hmin"], bbox["wmax"]), (bbox["hmax"], bbox["wmax"]), (bbox["hmax"], bbox["wmin"]) ]) ret_words = [] for w in self._words: # print((w._x0,w._y0),(w._x0,w._y1),(w._x1,w._y1),(w._x1,w._y0)) p2 = Polygon([(w._y0, w._x0), (w._y0, w._x1), (w._y1, w._x1), (w._y1, w._x0)]) if mode == "exact": if p1.contains(p2): ret_words.append(w) elif mode == "intersects": if p1.intersects(p2): ret_words.append(w) elif mode == "approximate": if p1.distance(p2) < min_dist: ret_words.append(w) return ret_words
def assign_value_labels_to_bars(self, bar_polygons, value_labels): # use the hungarian method ... but first compute all pairwise distances cost_matrix = np.zeros((len(bar_polygons), len(bar_polygons))) # ... fill the cost matrix ... for bar_idx, bar_polygon in enumerate(bar_polygons): bar_as_poly = Polygon(bar_polygon) for lbl_idx, val_label in enumerate(value_labels): lbl_as_poly = Polygon(val_label.position_polygon) cost_matrix[bar_idx, lbl_idx] = bar_as_poly.distance(lbl_as_poly) m = Munkres() assignments = m.compute(cost_matrix) bar_idx_to_value_label = {} for bar_idx, lbl_idx in assignments: try: bar_idx_to_value_label[bar_idx] = AxisValues.LabelNumericValue( value_labels[lbl_idx].value) except: # found a value label that cannot be interpreted ... # this will allow to fall back to projection-based bar value inference return None return bar_idx_to_value_label
def findIntersection(r, c, width, height, obj, frame_height, frame_width, isBox): captionPolygon = Polygon([(c, r), (c, r + height), (c + width, r + height), (c + width, r)]) objPolygon = None if isBox: x, y, width, height = obj objPolygon = Polygon([(x, y), (x + obj[2], y), (x + obj[2], y + obj[1]), (x, y + obj[1])]) obj = [[x, y], [x + obj[2], y], [x + obj[2], y + obj[1]], [x, y + obj[1]]] else: xs = np.array([p[0] for p in obj]) ys = np.array([p[1] for p in obj]) minxbound = np.min(xs) minybound = np.min(ys) maxwidth = np.max(xs) - minxbound maxheight = np.max(ys) - minybound objPolygon = Polygon([(minxbound, minybound), (minxbound + maxwidth, minybound), (minxbound + maxwidth, minybound - maxheight), (minxbound, minybound - maxheight)]) pointdists = np.array( [captionPolygon.distance(Point(point[0], point[1])) for point in obj]) minn = np.min(pointdists) maxx = np.max(pointdists) dist = (minn + maxx) / 2 * 10000000 return captionPolygon.intersection(objPolygon).area + dist
def move_turbines_within_boundary(turb_pos_x: list, turb_pos_y: list, boundary: Polygon, valid_region: Polygon ) -> (np.ndarray, float): """ :param turb_pos_x: list of x coordinates :param turb_pos_y: list of y coordinates :param boundary: site boundary :param valid_region: region to move turbines into :return: adjusted x and y coordinates """ squared_error: float = 0.0 num_turbines = len(turb_pos_x) for i in range(num_turbines): point = Point(turb_pos_x[i], turb_pos_y[i]) distance = valid_region.distance(point) if distance > 0: point = boundary.interpolate(boundary.project(point)) squared_error += distance ** 2 turb_pos_x[i] = point.x turb_pos_y[i] = point.y return turb_pos_x, turb_pos_y, squared_error
def is_equal(self, previous_regions, possible_actual_regions, timed_interval, km_per_h): distances = [] possible_combinations = itertools.product(previous_regions, possible_actual_regions) for prev, actual in possible_combinations: if len(prev) >= 3: previous_region = Polygon(prev) elif len(prev) == 2: previous_region = LineString(prev) else: previous_region = Point(prev[0]) if len(actual) >= 3: actual_region = Polygon(actual) elif len(actual) == 2: actual_region = LineString(actual) else: actual_region = Point(actual[0]) max_possible_distance = timed_interval * (km_per_h / 3.6) distance = previous_region.distance( actual_region) * self.meter_per_bin distances.append(distance) if distance <= max_possible_distance: return True, prev, actual, distance return False, None, None, min(distances)
def measure_range_region(reg_geom, range_set, weights=None): weight_sum = 0 if weights is None: weights = [1.0] * len(range_set) if isinstance(reg_geom, Disk): for i in range(len(range_set)): poly = Polygon(range_set[i]) pt = reg_geom.get_origin() pt_tpl = geometry.Point(pt[0], pt[1]) if poly.distance(pt_tpl) <= reg_geom.get_radius(): weight_sum += weights[i] elif isinstance(reg_geom, Halfplane): for i in range(len(range_set)): traj = Trajectory(range_set[i]) if reg_geom.intersects_trajectory(traj): weight_sum += weights[i] elif isinstance(reg_geom, Rectangle): rect = geometry.box(reg_geom.lowX(), reg_geom.lowY(), reg_geom.upX(), reg_geom.upY()) for i in range(len(range_set)): poly = Polygon(range_set[i]) if rect.intersects(poly): weight_sum += weights[i] else: raise ValueError() return weight_sum
def center_distance(pt1, pt2): if pt1 != pt1 or pt2 != pt2 or any(None in l for l in pt1) or any(None in l for l in pt2): return np.inf center1 = Polygon(pt1).centroid center2 = Polygon(pt2).centroid return center1.distance(center2)
def cal_space(self): wall1 = np.reshape(self.wall1, (-1, 2)) wall2 = np.reshape(self.wall2, (-1, 2)) theta = np.pi * self.angle / 180 # 以顺时针旋转为正 center = self.rotate_center # 旋转两个楼栋 wall1_lis = list() for i in range(len(wall1)): x0, y0 = wall1[i] new_x = (x0 - center[0]) * math.cos(theta) + ( y0 - center[1]) * math.sin(theta) + center[0] new_y = -(x0 - center[0]) * math.sin(theta) + ( y0 - center[1]) * math.cos(theta) + center[1] wall1_lis.append([round(new_x, 3), round(new_y, 3)]) wall2_lis = list() for i in range(len(wall2)): x0, y0 = wall2[i] new_x = (x0 - center[0]) * math.cos(theta) + ( y0 - center[1]) * math.sin(theta) + center[0] new_y = -(x0 - center[0]) * math.sin(theta) + ( y0 - center[1]) * math.cos(theta) + center[1] wall2_lis.append([round(new_x, 3), round(new_y, 3)]) wall1_ = np.array(wall1_lis) wall2_ = np.array(wall2_lis) center1 = [np.mean(wall1_[:, 0]), np.mean(wall1_[:, 1])] # 求楼栋几何中心点坐标 center2 = [np.mean(wall2_[:, 0]), np.mean(wall2_[:, 1])] x_min_1 = np.argmin(wall1_[:, 0]) x_max_1 = np.argmax(wall1_[:, 0]) x_min_2 = np.argmin(wall2_[:, 0]) x_max_2 = np.argmax(wall2_[:, 0]) extreme1 = [wall1_[x_min_1][0], wall1_[x_max_1][0]] # 求楼栋最左最右的x坐标 extreme2 = [wall2_[x_min_2][0], wall2_[x_max_2][0]] """仅用于判定是否存在遮挡现象""" if extreme1[0] > extreme2[1] or extreme1[1] < extreme2[0]: return False filter1 = self.initial(center2, center1, wall1_lis) filter2 = self.initial(center1, center2, wall2_lis) cover2 = self.get_loop(extreme1, filter2) cover1 = self.get_loop(extreme2, filter1) while len(cover1) < 3: cover1.append([cover1[-1][0] + 0.1, cover1[-1][1] + 0.1]) while len(cover2) < 3: cover2.append([cover2[-1][0] + 0.1, cover2[-1][1] + 0.1]) # 计算最短距离 w1 = np.reshape(cover1, (-1, 2)) w2 = np.reshape(cover2, (-1, 2)) w1 = Polygon(w1) w1 = gpd.geoseries.GeoSeries(w1) w2 = Polygon(w2) w2 = gpd.geoseries.GeoSeries(w2) dist = w2.distance(w1) return dist
def rect_distance(G, id1, id2): n1 = G.nodes[id1] n2 = G.nodes[id2] vertex1 = [(n1['xmin'], n1['ymin']), (n1['xmax'], n1['ymin']), (n1['xmax'], n1['ymax']), (n1['xmin'], n1['ymax'])] vertex2 = [(n2['xmin'], n2['ymin']), (n2['xmax'], n2['ymin']), (n2['xmax'], n2['ymax']), (n2['xmin'], n2['ymax'])] poly1 = Polygon(vertex1) poly2 = Polygon(vertex2) return poly1.distance(poly2)
def test_random_sample_triangle(a, b, c): # Assume that the area of the triangle is not zero. area = polygon_area(np.stack((a, b, c))) assume(not np.isclose(area, 0.0)) triangle = Polygon((a, b, c)) p = random_sample_triangle(a, b, c) point = Point(p) distance = triangle.distance(point) assert isinstance(p, np.ndarray) assert triangle.intersects(point) or np.isclose(distance, 0.0)
def distanceToPoly(poly_locs, query_loc): assert len(poly_locs) >= 3, "Needed at least 3 points to form Polygon" poly = Polygon([list(x) for x in poly_locs]) pt = query_loc.shapelyPoint() dist_magnitude = poly.exterior.distance(pt) dist_sign_indicator = poly.distance(pt) if dist_magnitude == 0: return 0 elif dist_sign_indicator == 0: return -dist_magnitude
def calculate_distance(self, point): if len(self.points) == 1: x = self.points[0][0] y = self.points[0][1] wall_point = Point(x, y) input_point = Point(point[0], point[1]) return wall_point.distance(input_point) elif len(self.points) == 2: wall_line = LineString(self.points) input_point = Point(point[0], point[1]) return wall_line.distance(input_point) else: x = point[0] y = point[1] polygon = Polygon(self.points) return polygon.distance(Point(x, y))
def get_closest_polygon(x, y): point = Point(x, y) min_dist = 10000 closest_polygon = None closest_room = None for m in MAP: polygon = Polygon(m['geometry']['coordinates']) dist = polygon.distance(point) if dist < min_dist: min_dist = dist closest_polygon = polygon closest_room = m['properties']['ref'] return closest_polygon, closest_room
def findIntersection(r, c, width, height, obj, frame_height, frame_width): xs = np.array([p[0] for p in obj]) ys = np.array([p[1] for p in obj]) minxbound = np.min(xs) minybound = np.min(ys) maxwidth = np.max(xs) - minxbound maxheight = np.max(ys) - minybound captionPolygon = Polygon([(c,r), (c, r + height), (c + width, r + height), (c + width, r)]) objPolygon = Polygon([(minxbound, minybound), (minxbound + maxwidth, minybound), (minxbound + maxwidth, minybound - maxheight), (minxbound, minybound - maxheight)]) pointdists = np.array([captionPolygon.distance(Point(point[0], point[1])) for point in obj]) minn = np.min(pointdists) maxx = np.max(pointdists) dist = (minn + maxx)/2 * 100000 return captionPolygon.intersection(objPolygon).area + dist
def iter_chars_on_line(chars, line, start_len, step=0.6): ''' Yields single character geometries placed on line. :param chars: iterable generated by ``generate_char_geoms`` :param line: :class:`shapely.geometry.LineString` :param start_len: length or start position on line as int or float :param step: distance a character is moved on line at each iteration (decrease for more accuracy and increase for faster rendering) :yields: character geometries as :class:`shapely.geometry.MultiLineString` ''' # make sure first character is not rendered directly at the edge of the line cur_len = max(start_len, 1) # geometry containing path of all rotated characters text_geom = Polygon() for paths, width, spacing in chars: cur_len += spacing last_rad = None for _ in xrange(30): # get current position on line pos = line.interpolate(cur_len) # get radians of gradient rad = linestring_char_radians(line, cur_len, width) #: only rotate if radians changed if rad != last_rad: rot_coords = tuple(tuple(rotate_coords(geom, rad)) for geom in paths) last_rad = rad # move rotated char to current position rot = MultiPolygon(tuple( Polygon(tuple(translate_coords(c, pos.x, pos.y))) for c in rot_coords )) # check whether distance to previous characters is long enough if ( text_geom.distance(rot) >= spacing or text_geom.geom_type == 'GeometryCollection' ): text_geom = text_geom.union(rot) cur_len += width yield rot break cur_len += step
def isCOMInSupportPlane(wantDistance): coordinate1 = ((rightFootSlotPosition[0] + 0.075), (rightFootSlotPosition[2] + 0.05)) #Right Foot, Front Edge coordinate2 = ((rightFootSlotPosition[0] - 0.025), (rightFootSlotPosition[2] + 0.05)) #Right Foot, Back Edge coordinate3 = ((leftFootSlotPosition[0] - 0.025), (leftFootSlotPosition[2] - 0.05)) #Left Foot, Back Edge coordinate4 = ((leftFootSlotPosition[0] + 0.075), (leftFootSlotPosition[2] - 0.05)) #Left Foot, Front Edge coordinate5 = ((robot.getCenterOfMass()[0]), (robot.getCenterOfMass()[2])) supportRectangle = Polygon([coordinate1,coordinate2,coordinate3,coordinate4]) COMPoint = Point(coordinate5) if(wantDistance== False): return supportRectangle.contains(COMPoint) elif(wantDistance == True): return supportRectangle.distance(COMPoint)
class Geofence(): def __init__(self, active): self.lat_filt = None self.lon_filt = None self.ts_last_check = 0. self.active = active # hack: does not work at north/south poles, and when longitude is ~180 self.in_geofence = not active # initialize false if geofence is active # get full geofenced polygon in lat and lon coordinates geofence_polygon = np.load(os.path.join(BASEDIR, 'selfdrive/controls/geofence_routes/press_demo.npy')) # for small latitude variations, we can assume constant conversion between longitude and meters (use the first point) self.longitude_deg_to_m = LATITUDE_DEG_TO_M * np.cos(np.radians(geofence_polygon[0,0])) # convert to m geofence_polygon_m = geofence_polygon * LATITUDE_DEG_TO_M geofence_polygon_m[:, 1] = geofence_polygon[:,1] * self.longitude_deg_to_m self.geofence_polygon = Polygon(geofence_polygon_m) def update_geofence_status(self, gps_loc, params): if self.lat_filt is None: # first time we get a location packet self.latitude = gps_loc.latitude self.longitude = gps_loc.longitude else: # apply a filter self.latitude = LOC_FILTER_K * gps_loc.latitude + (1. - LOC_FILTER_K) * self.latitude self.longitude = LOC_FILTER_K * gps_loc.longitude + (1. - LOC_FILTER_K) * self.longitude ts = sec_since_boot() if ts - self.ts_last_check > 1.: # tun check at 1Hz, since is computationally intense self.active = params.get("IsGeofenceEnabled") == "1" self.ts_last_check = ts p = Point([self.latitude * LATITUDE_DEG_TO_M, self.longitude * self.longitude_deg_to_m]) # histeresys geofence_distance = self.geofence_polygon.distance(p) if self.in_geofence and geofence_distance > GEOFENCE_THRESHOLD and self.active: self.in_geofence = False elif (not self.in_geofence and geofence_distance < 1.) or not self.active: self.in_geofence = True
def check_score(): """Check if solution produces networth specified in output.csv.""" with open("output.csv") as csvfile: df = pd.read_csv(csvfile) # Create a Polygon for each house. ps_houses = {} for row in df.iloc[:-1].loc[df.type != "WATER"].values: p = Polygon(tuple(map(float, c.split(","))) for c in row[1:-1]) ps_houses[row[0]] = p # Compute the free meters per house. free_space = {} house_polys = list(ps_houses.values()) for s, p in ps_houses.items(): other_houses = list(house_polys) other_houses.remove(p) free_space[s] = math.floor(p.distance(MultiPolygon(other_houses))) # Fetch structures per type and compute networths to make up the total # networth. base_worths = [2850, 3990, 6100] perc_incr = [3, 4, 6] networths = [0, 0, 0] for i, type in enumerate(TYPES[1:]): structures = df[df.type == type]["structure"].values networths[i] += base_worths[i] * 100 * len(structures) for s in structures: networths[i] += perc_incr[i] * free_space[s] \ * base_worths[i] if sum(networths) != int(df["corner_1"].iloc[-1]): raise check50.Failure("Networth in output.csv is not equal to the " "computed networth from the output.\n " f"Computed networth of {sum(networths):,} " "is made up of:\n" f"\t{networths[0]:,} \tfrom '{TYPES[1]}'\n" f"\t{networths[1]:,} \tfrom '{TYPES[2]}'\n" f"\t{networths[2]:,} \tfrom '{TYPES[3]}'\n")
def overlap(self, algo='concave'): """ project var backbone onto the plane of ref backbone as there's the problem of alpha value in concave hull generation, maybe I should set default to convex, see hull_test :param algo: concave/convex :return: area of the overlap, ref omol area, var omol area """ origin = self.ref.geoc ref_p = self.ref.vp ref_q = self.ref.vq ref_o = self.ref.vo ref = self.ref var = self.var ref_2dpts = [] var_2dpts = [] for i in range(len(ref)): ref_proj = get_proj_point2plane(ref[i], ref_o, origin) var_proj = get_proj_point2plane(var[i], ref_o, origin) ref_2d = coord_transform(ref_p, ref_q, ref_o, ref_proj)[:2] var_2d = coord_transform(ref_p, ref_q, ref_o, var_proj)[:2] ref_2dpts.append(ref_2d) var_2dpts.append(var_2d) if algo == 'concave': ref_hull, ref_edge_points = alpha_shape(ref_2dpts) var_hull, var_edge_points = alpha_shape(var_2dpts) else: # algo == 'convex': ref_hull = Polygon(ref_2dpts).convex_hull var_hull = Polygon(var_2dpts).convex_hull mindist2d = ref_hull.distance(var_hull) return (ref_hull.intersection(var_hull).area, float(ref_hull.area), float(var_hull.area), mindist2d)
def fixed_seats_model_with_radius(data_file, seat_radius, d0, d1=0, d2=0, d3=0, firstrow: bool = False, firstrow_y=0.0, type=1, num_selection=10, output_filename_affix='output'): ''' Create and solve IP model for selecting seats among a given set of fixed seats in a classroom while considering the physical space each seat occupies. :param data_file: str, coordinate file name of .csv or .xlsx file with 3 columns: Feature, X, Y. :param seat_radius: float, distance from center to side of seat space (assumed as a square). :param d0: float or int, social distance (inches) between seats. :param d1: float or int, social distance (inches) between seats and instructor. Default is 0. :param d2: float or int, safety distance (inches) from doors. Default is 0. :param d3: float or int, safety distance (inches) from aisles. Default is 0. :param firstrow: bool, False means incorporting seats of the first row, True means eliminating seats of the first row. Default is False. :param firstrow_y: float or int, the y-coordinate of seats in the first row. Default is 0. Required if firstrow is True :param type: int {1, 2, 3, 4}, if type=1: maximize number of selected seats under specified distance and prevention constraints. if type=2: maximize total distance while selecting specified number of students. if type=3: maximize minimum distance while selecting specified number of students. if type=4: minimize number of pairs of adjacent seats (next to each other in the same row). Default is 1. :param num_selection: int, the number of selected seats, required if type is 2, 3, or 4. Default is 10. :param output_filename_affix: str, adding to the end of input filename as output filename. :return: optimal obective function value, array of coordinates of selected seats, array of index of seats being selected in the parameter seat_loc. If type = 1, return the minimum distance between selected seats as well. ''' ## read coordinates file. if '.xlsx' in data_file: coordinates = pd.read_excel(data_file) filename = data_file[:-5] elif '.csv' in data_file: coordinates = pd.read_csv(data_file) filename = data_file[:-4] seat_loc = np.array(coordinates.loc[coordinates['Feature'] == 'seat', ['X', 'Y']]) pre_selected = np.array( coordinates.loc[coordinates['Feature'] == 'selected_seat', ['X', 'Y']]) aisles_loc = np.array(coordinates.loc[coordinates['Feature'] == 'aisle', ['X', 'Y']]) doors_loc = np.array(coordinates.loc[coordinates['Feature'] == 'door', ['X', 'Y']]) instructor_loc = np.array( coordinates.loc[coordinates['Feature'] == 'instructor', ['X', 'Y']]) if len(instructor_loc) == 1: instructor_loc = instructor_loc[0] ## filering seats by preventions seat_set = [i for i in range(len(seat_loc)) ] # contains all indexes of seats in seat_loc. # filtering seats by the instructor # We suggest if you consider the movement of instructor, then use 1)filtering by the first row; if considering instructor as a single point, then use 2)filtering by the instructor's location # 1)filtering by the first row. if firstrow == True: firstrow_seat_set = [] for i in range(len(seat_loc)): if seat_loc[i][1] != firstrow_y: firstrow_seat_set.append(i) seat_set = list(set(seat_set).intersection(firstrow_seat_set)) # 2)filtering by the instructor's location if d1 > 0: inst_seat_set = [] for i in range(len(seat_loc)): x_inst = np.abs(seat_loc[i][0] - instructor_loc[0]) y_inst = np.abs(seat_loc[i][1] - instructor_loc[1]) if np.sqrt(x_inst * x_inst + y_inst * y_inst) >= d1: inst_seat_set.append(i) seat_set = list(set(seat_set).intersection(inst_seat_set)) # filtering seats by doors if d2 > 0: doornum = len(doors_loc) door_seat_set = [] for i in range(len(seat_loc)): dist_to_door = 0 for j in range(doornum): x_door = np.abs(seat_loc[i][0] - doors_loc[j][0]) y_door = np.abs(seat_loc[i][1] - doors_loc[j][1]) if np.sqrt(x_door * x_door + y_door * y_door) >= d2: dist_to_door += 1 if dist_to_door >= doornum: door_seat_set.append(i) seat_set = list(set(seat_set).intersection(door_seat_set)) # filtering seats by aisles if d3 > 0: aislenum = len(aisles_loc) aisle_seat_set = [] for i in range(len(seat_loc)): dist_to_aisle = 0 for j in range(aislenum): x_aisle = np.abs(seat_loc[i][0] - aisles_loc[j][0]) y_aisle = np.abs(seat_loc[i][1] - aisles_loc[j][1]) if np.sqrt(x_aisle * x_aisle + y_aisle * y_aisle) >= d3: dist_to_aisle += 1 if dist_to_aisle >= aislenum: aisle_seat_set.append(i) seat_set = list(set(seat_set).intersection(aisle_seat_set)) # Now, we get indexes of all candidate seats after filtering by preventions pair_set = [] # define a set of seat index pair (s1, s2) for all s1 != s2. for s1 in range(len(seat_set) - 1): for s2 in range(s1 + 1, len(seat_set)): pair_set.append((seat_set[s1], seat_set[s2])) distance = { } # compute distance between each pair of seats (s1, s2) for all s1 != s2. for pair in pair_set: seat1_loc = seat_loc[pair[0]] seat2_loc = seat_loc[pair[1]] seat1_polygon = Polygon([ (seat1_loc[0] - seat_radius, seat1_loc[1] - seat_radius), (seat1_loc[0] - seat_radius, seat1_loc[1] + seat_radius), (seat1_loc[0] + seat_radius, seat1_loc[1] + seat_radius), (seat1_loc[0] + seat_radius, seat1_loc[1] - seat_radius) ]) seat2_polygon = Polygon([ (seat2_loc[0] - seat_radius, seat2_loc[1] - seat_radius), (seat2_loc[0] - seat_radius, seat2_loc[1] + seat_radius), (seat2_loc[0] + seat_radius, seat2_loc[1] + seat_radius), (seat2_loc[0] + seat_radius, seat2_loc[1] - seat_radius) ]) distance[pair] = seat1_polygon.distance(seat2_polygon) d_max = np.max(list(distance.values()) ) # get the largest distance between two different seats. neibor_set = [] # define a set of seat index neibor pair (s1, s2). for pair in pair_set: if distance[pair] <= 30: neibor_set.append(pair) model = Model('fixed_seat_layout') ## Set Gurobi parameters model.setParam('OutputFlag', False) ## objective 2, 3, 4 takes long time to run, so adjust some parameters. if type > 1: model.setParam('MIPGap', 0.05) model.setParam('MIPFocus', 3) ## Add variables # general variables for all types. x = model.addVars(seat_set, vtype=GRB.BINARY) # need for type 2, 3, 4. if type > 1: z = model.addVars(pair_set, vtype=GRB.BINARY) # build initial solution if input if len(pre_selected) > 0: for s in pre_selected: x[s].start = 1 for i in range(len(pre_selected) - 1): for j in range(i + 1, len(pre_selected)): z[(pre_selected[i], pre_selected[j])].start = 1 # need for type 3 if type == 3: min_d = model.addVar(lb=0, vtype=GRB.CONTINUOUS) ## Add constraints if type > 1: # student number constraint: need for type 2, 3, 4 model.addConstr(quicksum(x[s] for s in seat_set) == num_selection) ## social distancing limit constraint: need for all objectives. # need for type 1 if type == 1: for pair in pair_set: if distance[pair] < d0: model.addConstr(x[pair[0]] + x[pair[1]] <= 1) # need for type 2, 3, 4 else: for pair in pair_set: if distance[pair] < d0: model.addConstr(z[pair] == 0) model.addConstr(x[pair[0]] + x[pair[1]] <= 1) else: model.addConstr(z[pair] <= x[pair[1]]) model.addConstr(z[pair] <= x[pair[0]]) model.addConstr(z[pair] >= x[pair[0]] + x[pair[1]] - 1) # need for type 3. if type == 3: # model.addConstrs(z[pair] <= t[pair] for pair in pair_set) model.addConstrs(min_d - distance[pair] - d_max * (1 - z[pair]) <= 0 for pair in pair_set) ## Set objective function # type 1: maximize number of students if type == 1: model.setObjective(quicksum(x[s] for s in seat_set), GRB.MAXIMIZE) # type 2: maximize total distance if type == 2: model.setObjective( quicksum(distance[pair] * z[pair] for pair in pair_set) / num_selection, GRB.MAXIMIZE) # type 3: maximize min distance if type == 3: model.setObjective(min_d, GRB.MAXIMIZE) # type 4: minimize number of neibor pairs if type == 4: model.setObjective(quicksum(z[pair] for pair in neibor_set), GRB.MINIMIZE) ## Optimize the model model.optimize() ## Print and return the result status_code = { 1: 'LOADED', 2: 'OPTIMAL', 3: 'INFEASIBLE', 4: 'INF_OR_UNBD', 5: 'UNBOUNDED' } status = model.status print('The optimization status is {}'.format(status_code[status])) if status == 2: # Retrieve objective value print('Optimal objective value: {}'.format(model.objVal)) # Retrieve variable value and record selected seats' index and coordinates. seat_loc_selected = [] seat_selected = [] for s in seat_set: if x[s].x > 0: seat_loc_selected.append(seat_loc[s]) seat_selected.append(s) coordinates = coordinates.append( pd.DataFrame( [['selected_seat', seat_loc[s][0], seat_loc[s][1]]], columns=['Feature', 'X', 'Y'])) # save the output file. coordinates.to_excel(filename + '_' + output_filename_affix + '.xlsx', index=False) if type == 1: # for type 1, print and return the minimum distance between selected seats as well. selected_distance = [ ] # record distance between each pair of selected seats. for i in range(len(seat_selected) - 1): for j in range(i + 1, len(seat_selected)): selected_distance.append(distance[seat_selected[i], seat_selected[j]]) print('smallest distance: {}'.format(np.min(selected_distance))) return model.objVal, np.array( seat_loc_selected), seat_selected, np.min(selected_distance) else: return model.objVal, np.array(seat_loc_selected), seat_selected
for park_bureau,bureau_color in zip(park_bureaus, bureau_colors): park_json_file = open(park_bureau + '.geojson') park_json_data = load(park_json_file) park_features = park_json_data['features'] for park_feature in park_features: coordinates = chain.from_iterable(park_feature['geometry']['coordinates']) park_polygon = Polygon(map(tuple, coordinates)) min_distance = sys.maxsize min_name = "" for amtrak_station in amtrak_stations: distance = park_polygon.distance(amtrak_station['coordinates']) if distance < min_distance: min_distance = distance min_name = amtrak_station['station_name'] if park_feature['properties']['NAME1'] is not None : park_name = park_feature['properties']['NAME1'] else : park_name = "" park_feature['properties'] = {} park_feature['properties']['description'] = park_name + "<br>" park_feature['properties']['description'] += "Closest Station: " + min_name + "<br>"
def refine(sXs, sYs, invPtsU, invPtsD, movingX, movingY): radii_arr = [] dirVecs = [] movingX.append(movingX[0]) movingY.append(movingY[0]) for i in range(0, len(sXs)): radmag = math.sqrt((sXs[i] - invPtsU[i][0])**2 + (sYs[i] - invPtsU[i][1])**2) vect = [(invPtsU[i][0] - sXs[i]) / radmag, (invPtsU[i][1] - sYs[i]) / radmag] # adding unit vector directions of the up spokes dirVecs.append(vect) # adding lengths of the up spokes radii_arr.append(radmag) if i != 0 and i != len(sXs) - 1: radmag = math.sqrt((sXs[i] - invPtsD[i - 1][0])**2 + (sYs[i] - invPtsD[i - 1][1])**2) vect = [(invPtsD[i - 1][0] - sXs[i]) / radmag, (invPtsD[i - 1][1] - sYs[i]) / radmag] # adding unit vector directions of the down spokes dirVecs.append(vect) # adding lengths of the down spokes radii_arr.append(radmag) plotx = np.array(movingX) ploty = np.array(movingY) tups = np.array((plotx, ploty)).T shapePts = list(map(lambda x, y: (x, y), movingX, movingY)) polyPlot = Polygon(shapePts) def obj_func(radii, grad=None): total_loss = 0 for i, radius in enumerate(radii): ind = math.ceil((i) / 2) base_pt = [sXs[ind], sYs[ind]] direc = [dirVecs[i][0] * radius, dirVecs[i][1] * radius] bdry_pt = [base_pt[0] + direc[0], base_pt[1] + direc[1]] point = Point(bdry_pt[0], bdry_pt[1]) dist = polyPlot.exterior.distance(point) total_loss += dist**2 return total_loss import nlopt opt = nlopt.opt(nlopt.LN_NEWUOA, len(radii_arr)) opt.set_min_objective(obj_func) opt.set_maxeval(450) opLen = opt.optimize(radii_arr) boundPts = [] for i in range(0, len(sXs)): upx = sXs[i] + dirVecs[2 * i - 1][0] * opLen[2 * i - 1] upy = sYs[i] + dirVecs[2 * i - 1][1] * opLen[2 * i - 1] xUp = [sXs[i], upx] yUp = [sYs[i], upy] if i == 0: upx = sXs[i] + dirVecs[0][0] * opLen[0] upy = sYs[i] + dirVecs[0][1] * opLen[0] xUp = [sXs[i], upx] yUp = [sYs[i], upy] boundPts.append([upx, upy]) if i != 0 and i != len(sXs) - 1: downx = sXs[i] + dirVecs[2 * i][0] * opLen[2 * i] downy = sYs[i] + dirVecs[2 * i][1] * opLen[2 * i] boundPts.append([downx, downy]) xDown = [sXs[i], downx] yDown = [sYs[i], downy] # plt.plot(xDown, yDown,'k') # plt.plot(xUp, yUp,'k') # plt.plot(movingX, movingY, 'b') # plt.plot(sXs, sYs,'r') # plt.axis('scaled') # plt.show() angle = -1 * math.pi / 2 min_loss = 1 min_ang = 0 min_len = 0 def obj_func(angles, grad=None): total_loss = 0 for i, angle in enumerate(angles): ind = math.ceil((i) / 2) base_pt = [sXs[ind], sYs[ind]] bdry_pt = [dirVecs[i][0] * opLen[i], dirVecs[i][1] * opLen[i]] s = math.sin(angle) c = math.cos(angle) xnew = bdry_pt[0] * c - bdry_pt[1] * s ynew = bdry_pt[0] * s + bdry_pt[1] * c bdry_pt[0] = xnew + sXs[ind] bdry_pt[1] = ynew + sYs[ind] preFin = bdry_pt.copy() vec = [bdry_pt[0] - base_pt[0], bdry_pt[1] - base_pt[1]] unitV = vec / np.linalg.norm(vec) point = Point(bdry_pt[0], bdry_pt[1]) while polyPlot.exterior.distance(point) > 0.00000001: point = Point(bdry_pt[0], bdry_pt[1]) dispV = unitV * polyPlot.exterior.distance(point) if polyPlot.distance(point) == 0: bdry_pt[0] = bdry_pt[0] + dispV[0] bdry_pt[1] = bdry_pt[1] + dispV[1] else: bdry_pt[0] = bdry_pt[0] - dispV[0] bdry_pt[1] = bdry_pt[1] - dispV[1] sLength = math.hypot(bdry_pt[0] - sXs[ind], bdry_pt[1] - sYs[ind]) shortDist = -1 ptInd = -1 for j in range(0, len(movingX)): ptDist = math.hypot(bdry_pt[0] - movingX[j], bdry_pt[1] - movingY[j]) if ptDist < shortDist or shortDist == -1: shortDist = ptDist ptInd = j ldist = math.hypot(bdry_pt[0] - movingX[ptInd - 1], bdry_pt[1] - movingY[ptInd - 1]) if ptInd == 0: ldist = math.hypot(bdry_pt[0] - movingX[ptInd - 2], bdry_pt[1] - movingY[ptInd - 2]) rdist = math.hypot( bdry_pt[0] - movingX[(ptInd + 1) % len(movingX)], bdry_pt[1] - movingY[(ptInd + 1) % len(movingX)]) if ptInd == len(movingX) - 1: rdist = math.hypot(bdry_pt[0] - movingX[1], bdry_pt[1] - movingY[1]) left = False if ldist < rdist: left = True vector_1 = [bdry_pt[0] - base_pt[0], bdry_pt[1] - base_pt[1]] if left: vector_2 = [ movingX[ptInd] - movingX[ptInd - 1], movingY[ptInd] - movingY[ptInd - 1] ] if ptInd == 0: vector_2 = [ movingX[ptInd] - movingX[ptInd - 2], movingY[ptInd] - movingY[ptInd - 2] ] else: vector_2 = [ movingX[(ptInd + 1) % len(movingX)] - movingX[ptInd], movingY[(ptInd + 1) % len(movingX)] - movingY[ptInd] ] if ptInd == len(movingX) - 1: vector_2 = [ movingX[1] - movingX[ptInd], movingY[1] - movingY[ptInd] ] unit_vector_1 = vector_1 / np.linalg.norm(vector_1) unit_vector_2 = vector_2 / np.linalg.norm(vector_2) dot_product = np.dot(unit_vector_1, unit_vector_2) ang = np.arccos(dot_product) total_loss = total_loss + (1 - abs(math.sin(ang))) if angle < -1 * math.pi / 16 or angle > math.pi / 16: total_loss = total_loss + 100 return total_loss import nlopt angles = np.zeros((len(sXs) - 1) * 2) opt = nlopt.opt(nlopt.LN_NEWUOA, len(angles)) opt.set_min_objective(obj_func) opt.set_maxeval(600) finAng = opt.optimize(angles) finBdryPts = [] for i, angle in enumerate(finAng): ind = math.ceil((i) / 2) base_pt = [sXs[ind], sYs[ind]] bdry_pt = [dirVecs[i][0] * opLen[i], dirVecs[i][1] * opLen[i]] s = math.sin(angle) c = math.cos(angle) xnew = bdry_pt[0] * c - bdry_pt[1] * s ynew = bdry_pt[0] * s + bdry_pt[1] * c bdry_pt[0] = xnew + sXs[ind] bdry_pt[1] = ynew + sYs[ind] vec = [bdry_pt[0] - base_pt[0], bdry_pt[1] - base_pt[1]] unitV = vec / np.linalg.norm(vec) point = Point(bdry_pt[0], bdry_pt[1]) while polyPlot.exterior.distance(point) > 0.000000001: point = Point(bdry_pt[0], bdry_pt[1]) dispV = unitV * polyPlot.exterior.distance(point) if polyPlot.distance(point) == 0: bdry_pt[0] = bdry_pt[0] + dispV[0] bdry_pt[1] = bdry_pt[1] + dispV[1] else: bdry_pt[0] = bdry_pt[0] - dispV[0] bdry_pt[1] = bdry_pt[1] - dispV[1] spokeXs = [base_pt[0], bdry_pt[0]] spokeYs = [base_pt[1], bdry_pt[1]] finBdryPts.append(bdry_pt) # plt.plot(spokeXs, spokeYs,'k') shortDist = -1 ptInd = -1 for j in range(0, len(movingX)): ptDist = math.hypot(bdry_pt[0] - movingX[j], bdry_pt[1] - movingY[j]) if ptDist < shortDist or shortDist == -1: shortDist = ptDist ptInd = j ldist = math.hypot(bdry_pt[0] - movingX[ptInd - 1], bdry_pt[1] - movingY[ptInd - 1]) if ptInd == 0: ldist = math.hypot(bdry_pt[0] - movingX[ptInd - 2], bdry_pt[1] - movingY[ptInd - 2]) rdist = math.hypot(bdry_pt[0] - movingX[(ptInd + 1) % len(movingX)], bdry_pt[1] - movingY[(ptInd + 1) % len(movingX)]) if ptInd == len(movingX) - 1: rdist = math.hypot(bdry_pt[0] - movingX[1], bdry_pt[1] - movingY[1]) left = False if ldist < rdist: left = True vector_1 = [bdry_pt[0] - base_pt[0], bdry_pt[1] - base_pt[1]] if left: vector_2 = [ movingX[ptInd] - movingX[ptInd - 1], movingY[ptInd] - movingY[ptInd - 1] ] if ptInd == 0: vector_2 = [ movingX[ptInd] - movingX[ptInd - 2], movingY[ptInd] - movingY[ptInd - 2] ] else: vector_2 = [ movingX[(ptInd + 1) % len(movingX)] - movingX[ptInd], movingY[(ptInd + 1) % len(movingX)] - movingY[ptInd] ] if ptInd == len(movingX) - 1: vector_2 = [ movingX[1] - movingX[ptInd], movingY[1] - movingY[ptInd] ] unit_vector_1 = vector_1 / np.linalg.norm(vector_1) unit_vector_2 = vector_2 / np.linalg.norm(vector_2) dot_product = np.dot(unit_vector_1, unit_vector_2) ang = np.arccos(dot_product) # print(ang) # plt.plot(movingX, movingY, 'b') # plotX = sXs[0:-1] # plotX.append(sXs[-1]+3.5) # plotX[0] = plotX[0]-3.5 # plotY = sYs # plt.plot(sXs, sYs,'r') base_pt1 = [sXs[0], sYs[0]] bdry_pt1 = [ sXs[0] + dirVecs[0][0] * opLen[0], sYs[0] + dirVecs[0][1] * opLen[0] ] base_pt2 = [sXs[-1], sYs[-1]] bdry_pt2 = [ sXs[-1] + dirVecs[-1][0] * opLen[-1], sYs[-1] + dirVecs[-1][1] * opLen[-1] ] spokeXs = [base_pt1[0], bdry_pt1[0]] spokeYs = [base_pt1[1], bdry_pt1[1]] # finBdryPts.append(bdry_pt1) spokeXs = [base_pt2[0], bdry_pt2[0]] spokeYs = [base_pt2[1], bdry_pt2[1]] # plt.axis('scaled') # plt.show() return finBdryPts
from shapely.geometry import Polygon, Point import time polygon = Polygon([(0, 0), (1, 0), (1, 1), (0,1)]) points = [(0, 0), (1, 0), (1, 1), (0,1)] print(polygon.distance(Point(2, 2))) print(len(list(polygon.exterior.coords))) print(polygon.geom_type) start_time = int(round(time.time() * 1000)) for i in range(100): polygon = Polygon(points) print("time taken", int(round(time.time() * 1000)) - start_time) """ class WallOld: def __init__(self, points): self.regression = LinearRegression() self.slope = None #these self.b = None self.x_points = [] self.y_points = [] self.min = (-float('inf'), -float('inf')) self.max = (float('inf'), float('inf')) self.logger = Logger("WallOld")
wr.field('x',fieldType='N',size=20,decimal=3) wr.field('y',fieldType='N',size=20,decimal=3) for [x,y] in valid_points: wr.poly([[[x,y]]],shapeType=shapefile.POINT) wr.record([x,y]) wr.save('shapes\\nexrad_points') #--write a nearest-neighbor nexrad shapefile wr = shapefile.writer_like(shapename_nex) wr.field('group',fieldType='N',size=2,decimal=0) pmap = {} for shape,poly,record in zip(nexrad_shapes,nexrad_polygons,nexrad_records): imin,dist = None,1.0e+30 for i,v in enumerate(valid_Points): d = poly.distance(v) if d < dist: dist = d imin = i if imin in pmap.keys(): pmap[imin].append(record[0]) else: pmap[imin] = [record[0]] wr.poly([shape.points],shapeType=shape.shapeType) record.append(imin) wr.record(record) wr.save('shapes\\nexrad_groups') #--add the grouping to the grid shapefile wr = shapefile.writer_like(shapename_grid) wr.field('nex_group',fieldType='N',size=3,decimal=0)
type(countries.geometry[0]) # To construct one ourselves: from shapely.geometry import Point, Polygon, LineString p = Point(0, 0) print(p) polygon = Polygon([(1, 1), (2, 2), (2, 1)]) polygon.area polygon.distance(p) # <div class="alert alert-info" style="font-size:120%"> # # **REMEMBER**: <br> # # Single geometries are represented by `shapely` objects: # # * If you access a single geometry of a GeoDataFrame, you get a shapely geometry object # * Those objects have similar functionality as geopandas objects (GeoDataFrame/GeoSeries). For example: # * `singleShapelyObject.distance(other_point)` -> distance between two points # * `geodataframe.distance(other_point)` -> distance for each point in the geodataframe to the other point # # </div> # ## Plotting our different layers together
def inflate_polygon(vertices, points): """ Inflates the polygon such that it will contain all the given points. Parameters ---------- vertices : (Mx2) array The coordinates of the vertices of the polygon. points : (Mx2) array The coordinates of the points that the polygon should contain. Returns ------- vertices : (Mx2) array The coordinates of the vertices of the inflated polygon. """ new_vertices = vertices.copy() points_geom = [Point(p) for p in points] n_vertices = len(vertices) polygon = Polygon(vertices) edges = utils.create_pairs(new_vertices) # Find points not enclosed in polygon distances = np.array([polygon.distance(p) for p in points_geom]) outliers_mask = np.invert(np.isclose(distances, 0)) outliers = points[outliers_mask] distances = distances[outliers_mask] n_outliers = len(outliers) while n_outliers > 0: p = outliers[np.argmax(distances)] # Find nearest polygon edge to point point_on_polygon, _ = nearest_points(polygon, Point(p)) point_on_polygon = np.array(point_on_polygon) nearest_edges = point_polygon_edges(point_on_polygon, edges) # Move polygon edge out such that point is enclosed for i in nearest_edges: delta = p - point_on_polygon p1 = new_vertices[i] + delta p2 = new_vertices[(i + 1) % n_vertices] + delta # Lines l1 = BoundarySegment( np.array([new_vertices[(i - 1) % n_vertices], new_vertices[i]])) l2 = BoundarySegment(np.array([p1, p2])) l3 = BoundarySegment( np.array([ new_vertices[(i + 1) % n_vertices], new_vertices[(i + 2) % n_vertices] ])) # Intersections new_vertices[i] = l2.line_intersect(l1.line) new_vertices[(i + 1) % n_vertices] = l2.line_intersect(l3.line) # Update polygon polygon = Polygon(new_vertices) if not polygon.is_valid: polygon = polygon.buffer(0) new_vertices = np.array(polygon.exterior.coords) n_vertices = len(new_vertices) n_outliers = float('inf') edges = utils.create_pairs(new_vertices) point_on_polygon, _ = nearest_points(polygon, Point(p)) point_on_polygon = np.array(point_on_polygon) distances = np.array([polygon.distance(p) for p in points_geom]) outliers_mask = np.invert(np.isclose(distances, 0)) outliers = points[outliers_mask] distances = distances[outliers_mask] if len(outliers) >= n_outliers: break n_outliers = len(outliers) if not Polygon(new_vertices).is_valid and Polygon(vertices).is_valid: return vertices else: return new_vertices
class RCCar: def __init__(self, start_x, start_y): self.cur_x = start_x self.cur_y = start_y self.next_x = self.cur_x self.next_y = self.cur_y self.prev_x = self.cur_x self.prev_y = self.cur_y self.cur_theta = math.pi / 2 self.next_theta = self.cur_theta robot_hex = create_hexagon(self.cur_x, self.cur_y, RC_ROBOT_DIAMETER / 2) robot_shell = create_hexagon(self.cur_x, self.cur_y, RC_ROBOT_DIAMETER / 2 + MAX_SENSOR_DETECT) self.poly = Polygon(robot_hex) self.sensor_fields = [] # make 5 of the sensor fields for i in range(5): trap = Polygon([robot_shell[i], robot_hex[i], robot_hex[i + 1], robot_shell[i + 1]]) self.sensor_fields.append(trap) # last 6 trap = Polygon([robot_shell[5], robot_hex[5], robot_hex[0], robot_shell[0]]) self.sensor_fields.append(trap) self.penalties = 0 def find_next_frame_data(self, action): wheel_angular_velocities = self.action_to_rotational_velocity(action) wheel_linear_velocities = wheel_angular_velocities * WHEEL_DIAMETER / 2 w = (wheel_linear_velocities[1] - wheel_linear_velocities[0]) / WHEEL_DISTANCE if (wheel_linear_velocities[1] - wheel_linear_velocities[0]) < 0.01: self.next_x = self.cur_x + wheel_linear_velocities[0] * 1/FRAMES_PER_SECOND * math.cos(self.cur_theta) self.next_y = self.cur_y + wheel_linear_velocities[0] * 1/FRAMES_PER_SECOND * math.sin(self.cur_theta) self.next_theta = self.cur_theta return # turning in place, use one motor elif (wheel_linear_velocities[1] + wheel_linear_velocities[0]) < 0.01: wheel_linear_velocities[1] = 0 r = WHEEL_DISTANCE / 2 * ((wheel_linear_velocities[1] + wheel_linear_velocities[0]) / (wheel_linear_velocities[1] - wheel_linear_velocities[0])) icc = [self.cur_x - r * math.sin(self.cur_theta), self.cur_y + r * math.cos(self.cur_theta)] w_t = w * 1/FRAMES_PER_SECOND mod_x, mod_y = self.cur_x - icc[0], self.cur_y - icc[1] self.next_x = math.cos(w_t) * mod_x - math.sin(w_t) * mod_y self.next_y = math.sin(w_t) * mod_x + math.cos(w_t) * mod_y self.next_x += icc[0] self.next_y += icc[1] self.next_theta = w_t + self.cur_theta def apply_transform(self, dx, dy): for i in range(len(self.sensor_fields)): trap = self.sensor_fields[i] # apply dx, dy trap = affinity.translate(trap, dx, dy) self.sensor_fields[i] = trap # update robot polygon self.poly = affinity.translate(self.poly, dx, dy) self.cur_x += dx self.cur_y += dy def apply_rotation(self, dtheta): for i in range(len(self.sensor_fields)): trap = self.sensor_fields[i] # apply dtheta trap = affinity.rotate(trap, dtheta * 180/(math.pi), 'center') self.sensor_fields[i] = trap self.poly = affinity.rotate(self.poly, dtheta * 180/(math.pi), 'center') def update_robot_bounds(self, objects): self.prev_x = self.cur_x self.prev_y = self.cur_y # update sensor fields dx = self.next_x - self.cur_x dy = self.next_y - self.cur_y dtheta = self.next_theta - self.cur_theta self.apply_transform(dx, dy) self.apply_rotation(dtheta) # absolutes self.cur_x = self.next_x self.cur_y = self.next_y self.cur_theta = self.next_theta for obj in objects[1:]: # ignore car at index 0 if self.poly.contains(obj.poly) or self.poly.intersects(obj.poly): self.penalties += 1 # keep robot in bounds if self.cur_x > ROOM_DIM_X - RC_ROBOT_DIAMETER / 2: dx = ROOM_DIM_X - RC_ROBOT_DIAMETER / 2 - self.cur_x self.apply_transform(dx, 0) self.next_x = self.cur_x elif self.cur_x < 0 + RC_ROBOT_DIAMETER / 2: dx = (0 + RC_ROBOT_DIAMETER / 2) - self.cur_x self.apply_transform(dx, 0) self.next_x = self.cur_x if self.cur_y > ROOM_DIM_Y - RC_ROBOT_DIAMETER / 2: dy = (ROOM_DIM_Y - RC_ROBOT_DIAMETER / 2) - self.cur_y self.apply_transform(0, dy) self.next_y = self.cur_y elif self.cur_y < 0 + RC_ROBOT_DIAMETER / 2: dy = (0 + RC_ROBOT_DIAMETER / 2) - self.cur_y self.apply_transform(0, dy) self.next_y = self.cur_y def get_penalties(self): penalties = self.penalties self.penalties = 0 return penalties def action_to_rotational_velocity(self, action): return MAX_ANGULAR_VELOCITY * (action / 1.0) def update(self, action, objects): print(action) self.update_robot_bounds(objects) self.find_next_frame_data(action) def get_sensor_data(self, objects): """ Scans environment and determines if objects are in radar and if so to which sensor and the distance """ to_ret = [MAX_SENSOR_DETECT for _ in range(6)] for i, trap in enumerate(self.sensor_fields): for obj in objects[1:]: # ignore car at index 0 if trap.contains(obj.poly) or trap.intersects(obj.poly): dist = self.poly.distance(obj.poly) if dist < to_ret[i]: to_ret[i] = dist return to_ret
for park_bureau, bureau_color in zip(park_bureaus, bureau_colors): park_json_file = open(park_bureau + '.geojson') park_json_data = load(park_json_file) park_features = park_json_data['features'] for park_feature in park_features: coordinates = chain.from_iterable( park_feature['geometry']['coordinates']) park_polygon = Polygon(map(tuple, coordinates)) min_distance = sys.maxsize min_name = "" for amtrak_station in amtrak_stations: distance = park_polygon.distance(amtrak_station['coordinates']) if distance < min_distance: min_distance = distance min_name = amtrak_station['station_name'] if park_feature['properties']['NAME1'] is not None: park_name = park_feature['properties']['NAME1'] else: park_name = "" park_feature['properties'] = {} park_feature['properties']['description'] = park_name + "<br>" park_feature['properties'][ 'description'] += "Closest Station: " + min_name + "<br>"
def adjust_position(x, y, r, Na, Lx, Ly, d_min): poly_clip = [] dphi = 2.0 * math.pi / Na for ka in range(Na): ph = dphi / 2 + (ka - 1) * dphi px = x + r * math.cos(ph) py = y + r * math.sin(ph) poly_clip.append([px, py]) p = Polygon(poly_clip) delta = 1e-3 tmp = [] tmp.append([-Lx / 2 - delta, Ly / 2]) tmp.append([-Lx / 2, Ly / 2]) tmp.append([-Lx / 2, -Ly / 2]) tmp.append([-Lx / 2 - delta, -Ly / 2]) L = Polygon(tmp) tmp = [] tmp.append([Lx / 2, Ly / 2]) tmp.append([Lx / 2 + delta, Ly / 2]) tmp.append([Lx / 2 + delta, -Ly / 2]) tmp.append([Lx / 2, -Ly / 2]) R = Polygon(tmp) tmp = [] tmp.append([-Lx / 2, Ly / 2]) tmp.append([-Lx / 2, Ly / 2 + delta]) tmp.append([Lx / 2, Ly / 2 + delta]) tmp.append([Lx / 2, Ly / 2]) U = Polygon(tmp) tmp = [] tmp.append([-Lx / 2, -Ly / 2]) tmp.append([-Lx / 2, -Ly / 2 - delta]) tmp.append([Lx / 2, -Ly / 2 - delta]) tmp.append([Lx / 2, -Ly / 2]) B = Polygon(tmp) dx = 0 dy = 0 d = p.distance(U) if d < d_min and d > 0: dy += 2 * d_min d = p.distance(B) if d < d_min and d > 0: dy -= 2 * d_min d = p.distance(L) if d < d_min and d > 0: dx -= 2 * d_min d = p.distance(R) if d < d_min and d > 0: dx += 2 * d_min return dx, dy
class PanelGroup: """ this class is mainly used to store a panel group's geographical information """ def __init__(self, group_id: str, vertices_gps: List[Tuple[float, float]] = None, vertices_utm: List[Tuple[float, float, int]] = None): """ can be constructed with gps position or utm position, but better not both :param group_id: id of the panel group :param vertices_gps: list of (latitude, longitude) :param vertices_utm: list of (easting, northing, utm_zone_number) """ if vertices_gps is None: if vertices_utm is None: raise ValueError("gps or utm coordinates need to be provided") else: self._vertices_utm = vertices_utm self._vertices_gps = [utm.to_latlon(*x, northern=True) for x in vertices_utm] if vertices_gps is not None: if vertices_utm is None: self._vertices_gps = vertices_gps self._vertices_utm = [utm.from_latlon(x[0], x[1])[:3] for x in vertices_gps] else: raise ValueError("provide gps or utm only") # a polygon based on panel group's utm coordinates self._polygon = Polygon([(x[0], x[1]) for x in self._vertices_utm]) self._utm_zone = self._vertices_utm[0][2] self._group_id = group_id self._bounds = self._polygon.bounds @property def panel_group_id(self) -> Optional[str]: return self._group_id @property def utm_zone(self) -> int: return self._utm_zone @property def least_east(self) -> float: """ :return: least easting utm value, in meters """ return self._bounds[0] @property def most_east(self) -> float: """ :return: most easting utm value, in meters """ return self._bounds[2] @property def most_north(self) -> float: """ :return: most northing utm value, in meters """ return self._bounds[3] @property def least_north(self) -> float: """ :return: least northing utm value, in meters """ return self._bounds[1] @property def polygon(self) -> Polygon: """ return the panel group as a polygon, the coordinates is UTM coordinates :return: Polygon([(easting1, northing1), (easting2, northing2), ...]) """ return self._polygon def distance_to_utm(self, utm_pos: Tuple[float, float, int]) -> float: """ calculate the distance between the panel group to a position based on utm coordinates :param utm_pos: utm coordinates in (easting, northing, zone_number) :return: distance in meters """ if utm_pos[2] != self._utm_zone: raise ValueError("the point is not in the same utm zone with the panel group") point = Point(utm_pos[:2]) return self._polygon.distance(point) def distance_to_gps(self, gps: Tuple[float, float]) -> float: """ calculate the distance between the panel group and a pair of given gps coordinates :param gps: gps coordinates in (latitude, longitude) :return: distance in meters """ utm_pos = utm.from_latlon(*gps)[:3] return self.distance_to_utm(utm_pos) def nearest_utm(self, utm_pos: UTM) -> UTM: """take in a utm position and return the nearest position on the panel group to this point :param utm_pos: a utm position in form of (easting, northing, zone_number) :return: nearest position on the panel group, in form of (easting, northing, zone_number) """ if utm_pos[2] != self.utm_zone: raise ValueError("the point is not in the same utm zone") point = Point(utm_pos[:2]) nearest_point = nearest_points(point, self._polygon)[1] return nearest_point.x, nearest_point.y, self.utm_zone
def check_placement(): """Check if all objects are placed correctly.""" with open("output.csv") as csvfile: df = pd.read_csv(csvfile) # Create Polygons from the coordinates and check if they overlap. ps_water = {} ps_houses = {} overlap = [] for row in df[:-1].values: p = Polygon(tuple(map(float, c.split(","))) for c in row[1:-1]) if p.within(MultiPolygon(list(ps_water.values()))): overlap.append([row[0], "Water"]) if p.within(MultiPolygon(list(ps_houses.values()))): overlap.append([row[0], "House"]) if row[-1] == "WATER": ps_water[row[0]] = p else: ps_houses[row[0]] = p if overlap: error = "Structures may not overlap, but found:\n" for s in overlap: idx = df[df["structure"] == s[0]].index.tolist()[0] error = "".join([ error, f"\t{s[1]} was overlapped by '{s[0]}' " f" \ton row {idx + 2}\n" ]) raise check50.Failure(error) # Check if the area of the total map is 180x160. polys = list(ps_water.values()) polys.extend(list(ps_houses.values())) bounds = MultiPolygon(polys).bounds x_dim = bounds[2] - bounds[0] y_dim = bounds[3] - bounds[1] if x_dim > 180.0 or y_dim > 160.0: raise check50.Failure(f"The area has a dimension of " f"'{x_dim}x{y_dim}' and thus exceeds " f"180x160.") free_space = {} house_polys = list( ps_houses.values() ) # TODO: Add one big rectangle poly with hole in the middle for the map. min_extra_meters = [0, 2, 3, 6] invalid_houses = np.array([[0, 0, 0]], ndmin=2) # Check if the minimal extra meters for houses are correct. for s, p in ps_houses.items(): other_houses = list(house_polys) other_houses.remove(p) free_space[s] = math.floor(p.distance(MultiPolygon(other_houses))) s_type = df[df["structure"] == s]["type"].values[0] req_space = min_extra_meters[TYPES.index(s_type)] if req_space > free_space[s]: invalid_houses = np.append(invalid_houses, [[s, free_space[s], req_space]], axis=0) if invalid_houses[1:].size: error = "Structures with less than minimal free meters found:\n" for s, space, req_space in invalid_houses[1:]: idx = df[df["structure"] == s].index.tolist()[0] error = "".join([ error, f"\t'{s}' \t has {space} free meters " f"instead of {req_space} on row " f"{idx + 2}\n" ]) raise check50.Failure(error)
def adequate_spacing(m_hull, s_hull, tempoffset_x, tempoffset_y, the_dist): s_temp = list( map(lambda x: (x[0] + tempoffset_x, x[1] + tempoffset_y), s_hull)) poly1 = Polygon(m_hull) poly2 = Polygon(s_temp) return poly1.distance(poly2) >= the_dist