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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
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
Ejemplo n.º 13
0
 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))
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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)
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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")
Ejemplo n.º 20
0
    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>"
	    
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
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>"
Ejemplo n.º 30
0
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
Ejemplo n.º 31
0
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
Ejemplo n.º 32
0
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)
Ejemplo n.º 33
0
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