Beispiel #1
0
def filter_long_distance_lines_raw(lines, sheet_dict):
    # 去掉roi里面的线
    lines_tmp1 = []
    for index, region_box in enumerate(sheet_dict):
        coordinates = region_box['bounding_box']
        xmin = coordinates['xmin']
        ymin = coordinates['ymin']
        xmax = coordinates['xmax']
        ymax = coordinates['ymax']
        box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                               (xmin, ymax)])
        for line in lines:
            line_tmp = LineString([(line[0], line[1]), (line[2], line[3])])
            # line_tmp = LineString([(750, 502), (1035, 502)])
            decision = [
                line_tmp.within(box_polygon),
                line_tmp.contains(box_polygon),
                line_tmp.overlaps(box_polygon)
            ]
            # attention:[179, 440, 1092, 729]
            # 横线 750, 502, 1035, 509
            if True in decision:
                lines_tmp1.append(line)
    lines_tmp = [line for line in lines if line not in lines_tmp1]
    return lines_tmp
Beispiel #2
0
def filter_line_in_mark(lines, sheet_dict):
    # 去掉roi里面的线
    lines_tmp1 = []
    for index, region_box in enumerate(sheet_dict):
        class_name = region_box['class_name']
        if region_box['class_name'] == 'mark':
            coordinates = region_box['bounding_box']
            xmin = coordinates['xmin']
            ymin = coordinates['ymin']
            xmax = coordinates['xmax']
            ymax = coordinates['ymax']
            box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                                   (xmin, ymax)])
            for line in lines:
                line_tmp = LineString([(line[0], line[1]), (line[2], line[3])])
                # line_tmp = LineString([(750, 502), (1035, 502)])
                decision = [
                    line_tmp.within(box_polygon),
                    line_tmp.contains(box_polygon),
                    line_tmp.overlaps(box_polygon)
                ]
                # attention:[179, 440, 1092, 729]
                # 横线 750, 502, 1035, 509
                if True in decision:
                    lines_tmp1.append(line)
    lines_tmp = [line for line in lines if line not in lines_tmp1]
    for line in lines_tmp:
        cv2.line(image, (int(line[0]), int(line[1])),
                 (int(line[2]), int(line[3])), (0, 255, 0), 1, cv2.LINE_AA)
        # cv2.imwrite(r'E:\December\math_12_18\1_18\test_img\save3\mark.jpg', image)
    return lines_tmp
Beispiel #3
0
    def planets_are_aligned(self, day):
        """
        We need to check if all planets in this galaxy are in a straight line
        We will calculate a line from the first two planets and see if all
        others are inside of it.
        """
        line = LineString([
            self.planets[0].calculate_planet_position(day),
            self.planets[1].calculate_planet_position(day)
        ])

        for p in self.planets[2::]:
            if not line.contains(Point(p.calculate_planet_position(day))):
                return PlanetsPosition.NOT_ALIGNED

        if line.contains(Point(0, 0)):
            return PlanetsPosition.ALIGNED_WITH_THE_SUN
        return PlanetsPosition.ALIGNED_WITH_EACHOTHER
Beispiel #4
0
    def test_concave_polygon(self):
        """
        Finds pole of inaccessibility for a concave polygon and ensures that
        the point is inside.

        """
        concave_polygon = LineString([(500, 0), (0, 0), (0, 500),
                                      (500, 500)]).buffer(100)
        label = polylabel(concave_polygon)
        self.assertTrue(concave_polygon.contains(label))
Beispiel #5
0
    def test_concave_polygon(self):
        """
        Finds pole of inaccessibility for a concave polygon and ensures that
        the point is inside.

        """
        concave_polygon = LineString([(500, 0), (0, 0), (0, 500),
                                      (500, 500)]).buffer(100)
        label = polylabel(concave_polygon)
        self.assertTrue(concave_polygon.contains(label))
Beispiel #6
0
def is_oob(road_nodes, simulation_states):
    # Create the road geometry from the nodes. At this point nodes have been reversed already if needed.
    road_geometry = get_geometry(road_nodes)

    # Compute right polygon
    # Create the right lane polygon from the geometry
    left_edge_x = np.array([e['middle'][0] for e in road_geometry])
    left_edge_y = np.array([e['middle'][1] for e in road_geometry])
    right_edge_x = np.array([e['right'][0] for e in road_geometry])
    right_edge_y = np.array([e['right'][1] for e in road_geometry])

    # Compute the "short" edge at the end of the road to rule out false positives
    shorty = LineString([(left_edge_x[-1], left_edge_y[-1]), (right_edge_x[-1], right_edge_y[-1])]).buffer(2.0)

    # Note that one must be in reverse order for the polygon to close correctly
    right_edge = LineString(zip(right_edge_x[::-1], right_edge_y[::-1]))
    left_edge = LineString(zip(left_edge_x, left_edge_y))

    l_edge = left_edge.coords
    r_edge = right_edge.coords

    right_lane_polygon = Polygon(list(l_edge) + list(r_edge))

    #middle = [e['middle'] for e in road_geometry]
    #right = [e['right'] for e in road_geometry]
    #road_poly = [(p[0], p[1]) for p in middle]
    #right = [(p[0], p[1]) for p in right]
    #road_poly.extend(right[::-1])
    #right_polygon = Polygon(road_poly)


    first_oob_state = None
    position_of_first_oob_state = None
    for idx, simulation_state in enumerate(simulation_states):
        position = Point(simulation_state["pos"][0], simulation_state["pos"][1])
        if not right_lane_polygon.contains(position):

            # As soon as an observation is outside the lane polygon we mark the OOB, and return that position. All the
            # subsequent states will be removed/discarded
            log.debug("First OOB state found at %d", idx)
            first_oob_state = idx
            position_of_first_oob_state = position

            break

    if first_oob_state is not None:
        if shorty.contains(position_of_first_oob_state):
            log.info("*    False Positive. Short Edge")
            return False, None
        else:
            return True, first_oob_state
    else:
        return False, None
def find_points_in_region(positions: np.ndarray, region: LineString):
    """Find the points in a region.

    Parameters
    ----------
    positions: np.ndarray
        The positions of a trajectory.
    region: LineString
        The line region.
    """
    if region.is_empty:
        return []
    out = []
    for i, pt in enumerate(positions):
        if region.contains(Point(pt)):
            out.append(i)
    return out
Beispiel #8
0
def main():
    map = read_map("day10.txt")

    items = []
    points = []
    for line_id, line in enumerate(map):
        for item_id, item in enumerate(line):
            if item is "#":
                items.append((item_id, line_id))
                points.append(Point(item_id, line_id))

    best_el = None
    best_val = 0
    print("Number of asteroids: {}".format(len(items)))

    the_lazor_pos = (22, 19)

    t0 = time.time()
    for location in items:
        # check how many asteroids are visible
        cur_val = 0
        for asteroid in items:
            if asteroid is not location:
                line = LineString([location, asteroid])
                has_blocker = False
                for obs_id, obstacle in enumerate(items):
                    if (obstacle is not location) and (obstacle
                                                       is not asteroid):
                        if line.contains(points[obs_id]):
                            has_blocker = True
                            break

                if has_blocker is False:
                    cur_val += 1

        if cur_val > best_val:
            best_val = cur_val
            best_el = location

    t1 = time.time()

    print("Time: {}", t1 - t0)
    print("Element {} sees {}".format(best_el, best_val))
Beispiel #9
0
    def check_in_park(self, lat, lon):
        try:
            cell = Polygon(self.get_s2_cell_as_polygon(lat, lon, 20))  # s2 lvl 20
            if len(self.PARKS_CACHE) > 0:
                for p in self.PARKS_CACHE:
                    coords = p['coords']
                    # osm polygon can be a line
                    if len(coords) == 2:
                        shape = LineString(coords)
                        if shape.within(cell.centroid):
                            return { 'id' : p['id'], 'internal' : p['internal'], 'name' : p['name'] }
                    if len(coords) > 2:
                        shape = Polygon(coords)
                        if shape.contains(cell.centroid):
                            return {'id': p['id'], 'internal' : p['internal'], 'name': p['name']}
            return None

        except Exception as e:
            self.log.error('Unknown error: in check_in_park: {}',e)
            return None
Beispiel #10
0
def get_steps(point, route):
    """
    Calculate distance between start and intersection point
    :param point:
    :param route:
    :return:
    """
    result = 0
    route_len = len(route)
    for index in range(1, route_len):
        line = LineString([route[index - 1], route[index]])
        part_of = line.contains(point)
        if part_of:
            line = LineString([route[index - 1], (point.x, point.y)])
            result = result + line.length
            break
        else:
            result = result + line.length

    return result
Beispiel #11
0
def gym_data():
    gyms = []
    parks = get_all_parks()
    for g in get_gym_markers():
        gym_point = Point(g['lat'], g['lon'])
        cell = Polygon(get_s2_cell_as_polygon(g['lat'], g['lon'],
                                              20))  # s2 lvl 20
        for p in parks:
            coords = p['coords']
            # osm polygon can be a line
            if len(coords) == 2:
                shape = LineString(coords)
                if shape.within(cell.centroid):
                    gyms.append(g)
                    break
            if len(coords) > 2:
                shape = Polygon(coords)
                if shape.contains(cell.centroid):
                    gyms.append(g)
                    break
    return jsonify(gyms)
    def get_heading_angle(self):
        """ Return the heading angle of the car before it went OBE """
        # https://stackoverflow.com/questions/56710732/how-to-efficiently-calculate-full-2pi-angles-between-three-vectors-of-2d-point
        # https://stackoverflow.com/questions/14066933/direct-way-of-computing-clockwise-angle-between-2-vectors
        # https://newtonexcelbach.com/2014/03/01/the-angle-between-two-vectors-python-version/
        # dot = x1*x2 + y1*y2      # dot product between [x1, y1] and [x2, y2]
        # det = x1*y2 - y1*x2      # determinant
        # angle = atan2(det, dot)  # atan2(y, x) or atan2(sin, cos)

        # Obtain the right vectors from the various points
        A = np.array(
            [[self.state_before_obe.pos_x, self.state_before_obe.pos_y]])
        B = np.array([[self.obe_states[0].pos_x, self.obe_states[0].pos_y]])

        AB = B - A
        AB = AB

        proj = self.state_before_obe.get_path_projection()

        # This might be useful to add to asfault directly
        # Process the path two points at the time. The path define the road direction
        # https://gis.stackexchange.com/questions/84512/get-the-vertices-on-a-linestring-either-side-of-a-point
        # plt.show()
        # x, y = self.state_before_obe.test.get_path_polyline().coords.xy
        # plt.plot(x, y, color="yellow")
        # plt.plot(proj.x, proj.y, marker="o", color="blue")

        road_direction = None
        for pair in self._pairs(
                list(self.state_before_obe.test.get_path_polyline().coords)):
            # Check whether this pair contains the projection which by definition lies on the path
            # print("Checking if ", pair[0], pair[1], "contains", proj)
            # x, y = LineString([pair[0], pair[1]]).coords.xy
            # plt.plot(x, y, color="red")
            # plt.plot(proj.x, proj.y, marker="o")
            # This does not work despite
            segment = LineString([pair[0], pair[1]])
            if segment.contains(proj) or segment.buffer(EPS).contains(proj):
                road_direction = np.array([pair[0]]) - np.array([pair[1]])
                break

        P = np.array([[proj.x, proj.y]])

        # TODO How to decide this w.r.t. direction of the road?
        # Direction of the road might be given by the PATH of the test
        N = np.array([[-(P[0][1] - A[0][1]), (P[0][0] - A[0][0])]])
        N1 = np.array([[(P[0][1] - A[0][1]), -(P[0][0] - A[0][0])]])

        if road_direction is not None:
            if self.dot(road_direction, N) > 0:
                N = N1
        else:
            l.warning("CANNOT FIND THE ROAD DIRECTION FOR %s",
                      str(self.state_before_obe))

        # Vector defined by the last point before OBE and the first point of OBE
        # angle, is_cc = self.angle(N, AB)
        # print(angle, is_cc)

        angle = self.angle(AB, N)

        return angle[0]
Beispiel #13
0
def fld_demo4(image, sheet_dict, split_x, name, save_path):
    image_ = image.copy()
    img = Image.fromarray(image)
    t = time.time()
    img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # ret, binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    fld = cv2.ximgproc.createFastLineDetector()
    dlines = fld.detect(img_gray)
    lines = [line[0] for line in dlines.tolist()]

    lines_arr = np.array(lines)
    width_ = lines_arr[:, 2] - lines_arr[:, 0]
    height_ = lines_arr[:, 3] - lines_arr[:, 1]
    lines_index1 = np.where(width_ > 50)[0]
    lines_index2 = np.where(height_ > 50)[0]
    lines_index = np.hstack([lines_index1, lines_index2])
    new_lines = [lines[ele] for ele in lines_index]
    new_lines = clean_repeat_lines(new_lines)
    lines_tmp = filter_long_distance_lines(new_lines, sheet_dict)
    # lines_without_mark = filter_line_in_mark(new_lines, sheet_dict)

    # 检验滤线这一步骤有没有问题
    for dline in lines_tmp:
        x0 = int(round(dline[0]))
        y0 = int(round(dline[1]))
        x1 = int(round(dline[2]))
        y1 = int(round(dline[3]))
        cv2.line(image, (x0, y0), (x1, y1), (0, 255, 0), 1, cv2.LINE_AA)
        text = str([x0, y0, x1, y1])
        # cv2.putText(image, text, (x1, y1), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 1)
    # write_single_img(image, os.path.join(save_path, name + '_raw_lines' + '.jpg'))

    # get roi polygon 适当放大一点区域,使的线能包含在面里
    roi_box_polygon = []
    for index, region_box in enumerate(sheet_dict):
        if region_box['class_name'] in class_above_edge:
            coordinates = region_box['bounding_box']
            xmin = coordinates['xmin'] - 5
            ymin = coordinates['ymin'] - 5
            xmax = coordinates['xmax'] + 5
            ymax = coordinates['ymax'] + 5
            box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                                   (xmin, ymax)])
            roi_box_polygon.append(box_polygon)
            # cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255), 1)
        # cv2.imwrite(r'E:\111_4_26_test_img\aa\save\enlarge_box.jpg', image)

    # print(roi_box_polygon)

    # 对line进行分横向纵向
    landscape_list_tmp = []  # 横向
    longitudinal_list_tmp = []  # 纵向
    for ele in lines_tmp:
        if int(ele[2]) - int(ele[0]) < 10:  # 纵向
            longitudinal_list_tmp.append(ele)
        elif int(ele[3]) - int(ele[1]) < 10:  # 横向
            landscape_list_tmp.append(ele)
    # print(longitudinal_list_tmp)

    points_all_list = []
    points_list = []

    for index, box_polygon in enumerate(roi_box_polygon):
        extend_line_lan = LineString()
        extend_line_lon = LineString()
        # points_list = []
        for line1 in landscape_list_tmp:
            for line2 in longitudinal_list_tmp:
                # 这部分对原先出来的线进行增大
                raw_line_lan = LineString([(line1[0], line1[1]),
                                           (line1[2], line1[3])])  # 横向增加5个像素
                line_start_lan, line_end_lan = raw_line_lan.bounds[
                    0], raw_line_lan.bounds[1]

                raw_line_lon = LineString([(line2[0], line2[1]),
                                           (line2[2], line2[3])])  # 纵向的增加5个像素
                line_start_lon, line_end_lon = raw_line_lon.bounds[
                    0], raw_line_lon.bounds[1]

                # decision1 = [raw_line_lan.within(box_polygon), raw_line_lan.contains(box_polygon), raw_line_lan.overlaps(box_polygon)]
                # decision2 = [raw_line_lon.within(box_polygon), raw_line_lon.contains(box_polygon), raw_line_lon.overlaps(box_polygon)]

                decision1 = [
                    raw_line_lan.within(box_polygon),
                    raw_line_lan.contains(box_polygon)
                ]
                decision2 = [
                    raw_line_lon.within(box_polygon),
                    raw_line_lon.contains(box_polygon)
                ]
                if True in decision1 and True in decision2:
                    # 这里需要考虑延长左边还是右边
                    bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax = box_polygon.bounds[0], box_polygon.bounds[1], \
                                                                 box_polygon.bounds[2], box_polygon.bounds[3]

                    # if abs(line_start_lan - bbox_xmin) < abs(bbox_xmax - line_end_lan):
                    extend_line_lan = LineString([
                        (box_polygon.bounds[0], line1[1]),
                        (box_polygon.bounds[2], line1[3])
                    ])

                    # elif abs(line_start_lon - bbox_ymin) < abs(bbox_ymax - line_end_lon):
                    extend_line_lon = LineString([
                        (line2[0], box_polygon.bounds[1]),
                        (line2[2], box_polygon.bounds[3])
                    ])

                    cond1 = raw_line_lan.intersects(raw_line_lon)
                    cond2 = raw_line_lan.crosses(raw_line_lon)

                    cond3 = extend_line_lan.intersects(extend_line_lon)  # 十字交叉
                    cond4 = extend_line_lan.crosses(extend_line_lon)  # 十字交叉

                    xp, yp = 0.0, 0.0
                    if cond1:
                        (xp, yp
                         ) = raw_line_lan.intersection(raw_line_lon).bounds[:2]
                    elif cond3:
                        (xp, yp) = extend_line_lan.intersection(
                            extend_line_lon).bounds[:2]
                    points_list.append([(xp, yp), (raw_line_lan, raw_line_lon),
                                        (extend_line_lan, extend_line_lon),
                                        box_polygon])

    # TODO 验证找所有点的正确性
    # template = r'F:\exam\sheet_resolve\exam_info\000000-template.xml'
    # tree = ET.parse(template)
    # for ele in points_list:
    #     # for points2 in ele:
    #         # points1 = points_[1][0].bounds
    #         # points2 = points_[1][1].bounds
    #         # create_xml(str(points_[0]), tree, int(points1[0]), int(points1[1]), int(points1[2]), int(points1[3]))
    #         # create_xml(str(points_[0]), tree, int(points2[0]), int(points2[1]), int(points2[2]), int(points2[3]))
    #     points2 = ele[0]
    #     create_xml('points', tree, int(points2[0]), int(points2[1]), int(points2[0] + 1), int(points2[1] + 1))
    # tree.write(os.path.join(save_path, name + '.xml'))

    # 找出角点最优的那个
    # check points   判断点周围有没有黑色像素

    points_list_x = sorted(points_list, key=lambda k: k[0][0])
    sort_by_x = [ele[0] for ele in points_list_x]
    differ_new1 = np.array(sort_by_x[1:]) - np.array(sort_by_x[:-1])
    index_new1 = sorted(list(set(np.where(differ_new1 > 10.0)[0])))
    points_list_new_x = [points_list_x[ele] for ele in index_new1]

    points_list_y = sorted(points_list_new_x, key=lambda k: k[0][1])
    sort_by_y = [ele[0] for ele in points_list_y]
    differ_new2 = np.array(sort_by_y[1:]) - np.array(sort_by_y[:-1])
    index_new2 = sorted(list(set(np.where(differ_new2 > 10.0)[0])))
    points_list_new_y = [points_list_y[ele] for ele in index_new2]
    print('points_list:', points_list_new_y)

    pixel_point_all = judge_cross_point(points_list_new_y,
                                        image,
                                        name,
                                        thresh=30)
Beispiel #14
0
def get_direction(points_and_lines, box_polygon, image):
    image_height, image_width = image.shape[:2]
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)  # raw
    # cv2.imwrite(os.path.join(r'E:\December\math_12_18\1_18\test_img\save3\\', 'THRESH_BINARY_INV' + '.jpg'), binary)

    # DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT = 1, 2, 4, 8
    DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT = False, False, False, False

    # c++ 规则
    # CROSS_TL = DIR_UP | DIR_LEFT
    # CROSS_TR = DIR_UP | DIR_RIGHT
    # CROSS_TLR = DIR_UP | DIR_LEFT | DIR_RIGHT
    # CROSS_BL = DIR_DOWN | DIR_LEFT
    # CROSS_BR = DIR_DOWN | DIR_RIGHT
    # CROSS_BLR = DIR_DOWN | DIR_LEFT | DIR_RIGHT
    # CROSS_TBL = DIR_UP | DIR_DOWN | DIR_LEFT
    # CROSS_TBR = DIR_UP | DIR_DOWN | DIR_RIGHT
    # CROSS_TBLR = DIR_UP | DIR_DOWN | DIR_LEFT | DIR_RIGHT

    # python 规则
    # CROSS_TL = DIR_UP and DIR_LEFT
    # CROSS_TR = DIR_UP and DIR_RIGHT
    # CROSS_TLR = DIR_UP and DIR_LEFT and DIR_RIGHT
    # CROSS_BL = DIR_DOWN and DIR_LEFT
    # CROSS_BR = DIR_DOWN and DIR_RIGHT
    # CROSS_BLR = DIR_DOWN and DIR_LEFT and DIR_RIGHT
    # CROSS_TBL = DIR_UP and DIR_DOWN and DIR_LEFT
    # CROSS_TBR = DIR_UP and DIR_DOWN and DIR_RIGHT
    # CROSS_TBLR = DIR_UP and DIR_DOWN and DIR_LEFT and DIR_RIGHT
    # rule_list = [CROSS_TL, CROSS_TR, CROSS_TLR, CROSS_BL, CROSS_BR, CROSS_BLR, CROSS_TBL, CROSS_TBR, CROSS_TBLR]

    # 因为延长的线可能出问题,这里用的是原始的线
    print('points_and_lines:', points_and_lines)
    points = points_and_lines[0]
    raw_line = points_and_lines[1]

    point_x = int(points[0])
    point_y = int(points[1])
    # if point_x == 1620 and point_y == 3260:

    bbox = box_polygon.bounds
    left_boarder = int(bbox[0]) - point_x if int(bbox[0]) - point_x > 0 else 0
    right_boarder = int(bbox[2]) + point_x if int(
        bbox[2]) + point_x < image_width else image_width
    top_boarder = int(bbox[1]) - point_y if int(bbox[1]) - point_y > 0 else 0
    bottom_boarder = int(bbox[3]) + point_y if int(
        bbox[3]) + point_y < image_height else image_height

    cv2.rectangle(image, (left_boarder, top_boarder),
                  (right_boarder, bottom_boarder), (255, 0, 255), 1)

    raw_line_lan_ = raw_line[0]
    raw_line_lon_ = raw_line[1]

    if abs(raw_line_lan_.bounds[2] - point_x) >= abs(raw_line_lan_.bounds[0] -
                                                     point_x):
        raw_line_lan = LineString([(point_x, raw_line_lan_.bounds[1]),
                                   (raw_line_lan_.bounds[2],
                                    raw_line_lan_.bounds[3])])
    else:
        raw_line_lan = LineString([(raw_line_lan_.bounds[0],
                                    raw_line_lan_.bounds[1]),
                                   (point_x, raw_line_lan_.bounds[3])])

    if abs(raw_line_lon_.bounds[3] - point_y) <= abs(point_y -
                                                     raw_line_lon_.bounds[1]):
        raw_line_lon = LineString([(raw_line_lon_.bounds[0],
                                    raw_line_lon_.bounds[1]),
                                   (raw_line_lon_.bounds[2], point_y)])
    else:
        raw_line_lon = LineString([(raw_line_lon_.bounds[0], point_y),
                                   (raw_line_lon_.bounds[2],
                                    raw_line_lon_.bounds[3])])

    # box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)])

    right_area = Polygon([(point_x, point_y - 10),
                          (right_boarder, point_y - 10),
                          (right_boarder, point_y + 10),
                          (point_x, point_y + 10)])

    # 横线
    cv2.line(image, (int(raw_line_lan.bounds[0]), int(raw_line_lan.bounds[1])),
             (int(raw_line_lan.bounds[2]), int(raw_line_lan.bounds[3])),
             (255, 0, 0), 1, cv2.LINE_AA)

    # cv2.line(image, (int(raw_line_lan_.bounds[0]), int(raw_line_lan_.bounds[1])),
    #          (int(raw_line_lan_.bounds[2]), int(raw_line_lan_.bounds[3])), (255, 255, 0), 1, cv2.LINE_AA)

    # 纵线
    cv2.line(image, (int(raw_line_lon.bounds[0]), int(raw_line_lon.bounds[1])),
             (int(raw_line_lon.bounds[2]), int(raw_line_lon.bounds[3])),
             (255, 0, 0), 1, cv2.LINE_AA)

    # cv2.line(image, (int(raw_line_lon_.bounds[0]), int(raw_line_lon_.bounds[1])),
    #          (int(raw_line_lon_.bounds[2]), int(raw_line_lon_.bounds[3])), (255, 255, 0), 1, cv2.LINE_AA)

    cv2.rectangle(image,
                  (int(right_area.bounds[0]), int(right_area.bounds[1])),
                  (int(right_area.bounds[2]), int(right_area.bounds[3])),
                  (255, 0, 255), 1)

    # cv2.imwrite(r'E:\December\math_12_18\1_18\test_img\save3\extend_lines_by_bbox.jpg', image)

    # 水平向右
    decision = [
        raw_line_lan.within(right_area),
        raw_line_lan.contains(right_area),
        raw_line_lan.crosses(right_area)
    ]
    if True in decision:
        DIR_RIGHT = True

    # 水平向左
    left_area = Polygon([(left_boarder, point_y - 10), (point_x, point_y - 10),
                         (point_x, point_y + 10),
                         (left_boarder, point_y + 10)])
    decision = [
        raw_line_lan.within(left_area),
        raw_line_lan.contains(left_area),
        raw_line_lan.crosses(left_area)
    ]
    if True in decision:
        DIR_LEFT = True

    # box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)])
    # 垂直向上
    top_area = Polygon([(point_x - 10, top_boarder),
                        (point_x + 10, top_boarder), (point_x + 10, point_y),
                        (point_x - 10, point_y)])
    decision = [
        raw_line_lon.within(top_area),
        raw_line_lon.contains(top_area),
        raw_line_lon.crosses(top_area)
    ]
    if True in decision:
        DIR_UP = True

    # 垂直向下
    bottom_area = Polygon([(point_x - 10, point_y), (point_x + 10, point_y),
                           (point_x + 10, bottom_boarder),
                           (point_x - 10, bottom_boarder)])
    decision = [
        raw_line_lon.within(bottom_area),
        raw_line_lon.contains(bottom_area),
        raw_line_lon.crosses(bottom_area)
    ]
    if True in decision:
        DIR_DOWN = True

    CROSS_TL = DIR_UP and DIR_LEFT
    CROSS_TR = DIR_UP and DIR_RIGHT
    CROSS_TLR = DIR_UP and DIR_LEFT and DIR_RIGHT
    CROSS_BL = DIR_DOWN and DIR_LEFT
    CROSS_BR = DIR_DOWN and DIR_RIGHT
    CROSS_BLR = DIR_DOWN and DIR_LEFT and DIR_RIGHT
    CROSS_TBL = DIR_UP and DIR_DOWN and DIR_LEFT
    CROSS_TBR = DIR_UP and DIR_DOWN and DIR_RIGHT
    CROSS_TBLR = DIR_UP and DIR_DOWN and DIR_LEFT and DIR_RIGHT

    direction_dict = {
        0: 'CROSS_TL',
        1: 'CROSS_TR',
        2: 'CROSS_TLR',
        3: 'CROSS_BL',
        4: 'CROSS_BR',
        5: 'CROSS_BLR',
        6: 'CROSS_TBL',
        7: 'CROSS_TBR',
        8: 'CROSS_TBLR',
    }
    rule_list_tmp = [
        CROSS_TL, CROSS_TR, CROSS_TLR, CROSS_BL, CROSS_BR, CROSS_BLR,
        CROSS_TBL, CROSS_TBR, CROSS_TBLR
    ]
    index_ = np.where(np.array(rule_list_tmp) == True)[0]
    if len(index_) == 0:
        print('没找到方向:', points)
        return None
    else:
        print('index_:', index_)
        direction = direction_dict[index_[0]]
        return direction
Beispiel #15
0
def seilingstid(hale_df, tellelinje1, tellelinje2, returner_hale_index=False):
    """
    MODIFISERT MENON-KODE
    Klipper alle haler i hale_df som passerer både tellelinje 1 og 2 og
    returnerer segmentene som ligger mellom, samt tilhørende seilingstid brukt
    mellom linjene, lengde på seilasen mellom linjene i m og gjennomsnittlig
    hastighet i m/s.

    Funksjonen er så lang som den er for å håndtere edge-cases som i stor grad
    resulterer av at shapely.split() har en bug ved selv-kryssende linjer. Om
    denne skulle bli fikset så kan funksjonen potensielt skrives om.

    Input:
    hale_df:                pandas dataframe med haler
    tellelinje 1/2:         i vilkårlig rekkefølge, shapely geometrier
    returner_hale_index:    hvis True, returnerer en liste indexer av samme
                            lengde som klipp-outputen som korresponderer til
                            halene brukt i hvert av klippene.

    Output:
    klipp_df:               pandas dataframe som inneholder klippene
    [hale_indices]:         liste med indexer (se returner_hale_index)


    ADVARSEL: behandler kun ca. 50 haler i sekundet
    """

    #projeksjonen antar at input er en epsg:4326-projeksjon, som er standard for geosatelittdata
    #denne brukes for å regne om klippenes lengde fra epsg:4326-koordinater til nautiske mil
    #projeksjon = partial(pyproj.transform,
    #pyproj.Proj(init='epsg:4326'),
    #pyproj.Proj(init='epsg:32632'))

    klipp_df = gpd.GeoDataFrame()
    #hvis returner_hale_index er True vil denne fylles med indexer fra hale_df korresponderende til klippene i klipp_df
    hale_indices = []

    #iterer over haler
    for idx, hale_serie in hale_df.iterrows():
        hale = hale_serie.geometry
        hale_punkter = [Point(p) for p in hale.coords]

        #sjekker først om halen krysser begge tellelinjene
        if hale.intersects(tellelinje1) and hale.intersects(tellelinje2):

            #henter ut punktene der halen og tellelinjene krysser
            intersect_punkter_1 = hale.intersection(tellelinje1)
            intersect_punkter_2 = hale.intersection(tellelinje2)

            #dersom det kun finnes ett krysningspunkt per tellelinje puttes det i en liste for å funke i for-loopen senere
            if isinstance(intersect_punkter_1, Point):
                intersect_punkter_1 = [intersect_punkter_1]
            elif isinstance(
                    intersect_punkter_1,
                    LineString):  #for aa vaere kompatibel med polygoner
                intersect_punkter_1 = [
                    Point(p) for p in intersect_punkter_1.coords
                ]
            elif isinstance(
                    intersect_punkter_1[0],
                    LineString):  #for aa vaere kompatibel med polygoner
                temp = []
                for l in intersect_punkter_1:
                    temp.extend([Point(p) for p in l.coords])
                intersect_punkter_1 = temp

            if isinstance(intersect_punkter_2, Point):
                intersect_punkter_2 = [intersect_punkter_2]
            elif isinstance(
                    intersect_punkter_2,
                    LineString):  #for aa vaere kompatibel med polygoner
                intersect_punkter_2 = [
                    Point(p) for p in intersect_punkter_2.coords
                ]
            elif isinstance(
                    intersect_punkter_2[0],
                    LineString):  #for aa vaere kompatibel med polygoner
                temp = []
                for l in intersect_punkter_2:
                    temp.extend([Point(p) for p in l.coords])
                intersect_punkter_2 = temp

            intersect_idx_1 = []
            intersect_idx_2 = []
            intersect_time_1 = []
            intersect_time_2 = []

            #spar på punktene der halen krysser tellelinjene så de kan legges inn i klippet
            krysningspunkter_1 = []
            krysningspunkter_2 = []

            #iterer over krysningspunktene
            for punkt in intersect_punkter_1:

                #regn ut avstander fra hvert punkt i halen til krysningspunktene
                #(kan effektiviseres ved å filtrere ut hale-punkter utenfor loopen)
                point_distances = np.array([
                    hale_punkt.distance(punkt) for hale_punkt in hale_punkter
                ])

                #henter lokale minimum i avstand for å finne potensielle krysningspunkter.
                #NB: antar at halen ikke begynner eller slutter på et krysningspunkt
                local_minima = np.where(
                    np.r_[True, point_distances[1:] <= point_distances[:-1]]
                    & np.r_[point_distances[:-1] <= point_distances[1:],
                            True])[0]

                #iterer over de potensielle krysningspunktene
                for minima in local_minima:
                    #hent avstand til forrige og neste punkt
                    linje_bak, linje_frem = None, None

                    if minima > 0:
                        linje_bak = LineString(
                            [hale_punkter[minima],
                             hale_punkter[minima - 1]]).buffer(0.0001)
                    if minima < len(hale_punkter) - 1:
                        linje_frem = LineString(
                            [hale_punkter[minima],
                             hale_punkter[minima + 1]]).buffer(0.0001)

                    if linje_bak is not None and linje_bak.contains(punkt):
                        #legger til indexen til det nærmeste hale-punktet til krysningspunktet
                        #(tiden hentes ut her fordi det tillater inerpolering,
                        #men for øyeblikket støttes ikke dette)
                        intersect_idx_1.append(minima)
                        krysningspunkter_1.append(punkt)
                        weight = point_distances[minima - 1] / hale_punkter[
                            minima - 1].distance(hale_punkter[minima])
                        intersect_time_1.append(
                            hale_serie.times[minima - 1] +
                            ((hale_serie.times[minima] -
                              hale_serie.times[minima - 1]) * weight))
                    elif linje_frem is not None and linje_frem.contains(punkt):
                        #krysning funnet
                        intersect_idx_1.append(minima)
                        krysningspunkter_1.append(punkt)
                        weight = point_distances[minima] / hale_punkter[
                            minima].distance(hale_punkter[minima + 1])
                        intersect_time_1.append(hale_serie.times[minima] + (
                            (hale_serie.times[minima + 1] -
                             hale_serie.times[minima]) * weight))

            #se kommentarer for intersect_punkter_1
            for punkt in intersect_punkter_2:

                point_distances = np.array([
                    hale_punkt.distance(punkt) for hale_punkt in hale_punkter
                ])
                local_minima = np.where(
                    np.r_[True, point_distances[1:] <= point_distances[:-1]]
                    & np.r_[point_distances[:-1] <= point_distances[1:],
                            True])[0]

                for minima in local_minima:

                    linje_bak, linje_frem = None, None

                    if minima > 0:
                        linje_bak = LineString(
                            [hale_punkter[minima],
                             hale_punkter[minima - 1]]).buffer(0.01)
                    if minima < len(hale_punkter) - 1:
                        linje_frem = LineString(
                            [hale_punkter[minima],
                             hale_punkter[minima + 1]]).buffer(0.01)

                    if linje_bak is not None and linje_bak.contains(punkt):
                        intersect_idx_2.append(minima)
                        krysningspunkter_2.append(punkt)
                        weight = point_distances[minima - 1] / hale_punkter[
                            minima - 1].distance(hale_punkter[minima])
                        intersect_time_2.append(
                            hale_serie.times[minima - 1] +
                            ((hale_serie.times[minima] -
                              hale_serie.times[minima - 1]) * weight))

                    elif linje_frem is not None and linje_frem.contains(punkt):
                        intersect_idx_2.append(minima)
                        krysningspunkter_2.append(punkt)
                        weight = point_distances[minima] / hale_punkter[
                            minima].distance(hale_punkter[minima + 1])
                        intersect_time_2.append(hale_serie.times[minima] + (
                            (hale_serie.times[minima + 1] -
                             hale_serie.times[minima]) * weight))

            #henter ut de unike hale-punkt-indexene
            unq1, unq_idx1 = np.unique(intersect_idx_1, return_index=True)
            unq2, unq_idx2 = np.unique(intersect_idx_2, return_index=True)

            intersect_idx_1 = unq1
            intersect_idx_2 = unq2

            krysningspunkter_1 = [krysningspunkter_1[u] for u in unq_idx1]
            krysningspunkter_2 = [krysningspunkter_2[u] for u in unq_idx2]

            #henter ut de tilsvarende hale-tid indexene
            intersect_time_1 = np.array(intersect_time_1)[unq_idx1]
            intersect_time_2 = np.array(intersect_time_2)[unq_idx2]

            #i tilfelle punktene ikke er sortert etter tid
            time_sort_idx_1 = np.argsort(intersect_time_1)
            time_sort_idx_2 = np.argsort(intersect_time_2)

            #sorterer etter tid
            intersect_idx_1 = list(intersect_idx_1[time_sort_idx_1])
            intersect_idx_2 = list(intersect_idx_2[time_sort_idx_2])

            intersect_time_1 = list(intersect_time_1[time_sort_idx_1])
            intersect_time_2 = list(intersect_time_2[time_sort_idx_2])

            krysningspunkter_1 = [
                krysningspunkter_1[t] for t in time_sort_idx_1
            ]
            krysningspunkter_2 = [
                krysningspunkter_2[t] for t in time_sort_idx_2
            ]

            #iterer over krysningspunktene og hent ut krysningsparene.
            #lag så en dataframe av geometri, tidspunkter, utregnet avstand
            #samt hastighet.

            while len(intersect_idx_1) > 0 and len(intersect_idx_2) > 0:
                start_idx = None
                slutt_idx = None
                klipp_start = None
                klipp_slutt = None
                hale_klippet = None
                foerste_kryss = None

                if intersect_idx_1[0] < intersect_idx_2[0]:

                    if len(intersect_idx_1
                           ) > 1 and intersect_idx_1[1] < intersect_idx_2[0]:
                        krysningspunkter_1 = krysningspunkter_1[1:]
                        intersect_idx_1 = intersect_idx_1[1:]
                        intersect_time_1 = intersect_time_1[1:]

                    else:
                        start_idx = intersect_idx_1[0]
                        slutt_idx = intersect_idx_2[0]

                        klipp_start = intersect_time_1[0]
                        klipp_slutt = intersect_time_2[0]

                        foerste_kryss = 1
                        krysningspunkter_1 = krysningspunkter_1[1:]
                        krysningspunkter_2 = krysningspunkter_2[1:]

                        intersect_idx_1 = intersect_idx_1[1:]
                        intersect_idx_2 = intersect_idx_2[1:]

                        intersect_time_1 = intersect_time_1[1:]
                        intersect_time_2 = intersect_time_2[1:]

                else:

                    if len(intersect_idx_2
                           ) > 1 and intersect_idx_2[1] < intersect_idx_1[0]:
                        krysningspunkter_2 = krysningspunkter_2[1:]
                        intersect_idx_2 = intersect_idx_2[1:]
                        intersect_time_2 = intersect_time_2[1:]

                    else:
                        start_idx = intersect_idx_2[0]
                        slutt_idx = intersect_idx_1[0]

                        intersect_idx_2 = intersect_idx_2[1:]
                        intersect_idx_1 = intersect_idx_1[1:]

                        klipp_start = intersect_time_2[0]
                        klipp_slutt = intersect_time_1[0]

                        intersect_time_2 = intersect_time_2[1:]
                        intersect_time_1 = intersect_time_1[1:]

                        foerste_kryss = 2
                        krysningspunkter_1 = krysningspunkter_1[1:]
                        krysningspunkter_2 = krysningspunkter_2[1:]

                if slutt_idx is None or slutt_idx - start_idx <= 1:
                    continue

                hale_klippet = LineString(hale_punkter[start_idx:slutt_idx])
                lengde = distance_points(
                    hale_punkter[start_idx],
                    hale_punkter[slutt_idx]) * 1000  #metrisk meter

                tid_brukt = (klipp_slutt - klipp_start).total_seconds()

                klipp_df = klipp_df.append(
                    gpd.GeoDataFrame([[
                        hale_serie.mmsi, klipp_start, klipp_slutt, lengde,
                        lengde / tid_brukt, foerste_kryss, hale_klippet
                    ]],
                                     columns=[
                                         'mmsi', 'start_tid', 'slutt_tid',
                                         'lengde', 'obs_speed',
                                         'første_linje_krysset', 'geometry'
                                     ],
                                     geometry='geometry'))

                if returner_hale_index:
                    hale_indices.append(idx)

    if klipp_df.shape[0] > 0:
        klipp_df = klipp_df.set_geometry('geometry')

    if returner_hale_index:
        return klipp_df, hale_indices

    return klipp_df
Beispiel #16
0
def filter_long_distance_lines(lines, sheet_dict):
    # 去掉roi里面的线  也去掉mark里的线
    lines_tmp1 = []
    for index, region_box in enumerate(sheet_dict):
        if region_box['class_name'] in class_above_edge:
            coordinates = region_box['bounding_box']
            xmin = coordinates['xmin'] + 10
            ymin = coordinates['ymin'] + 10
            xmax = coordinates['xmax'] - 10
            ymax = coordinates['ymax'] - 10
            box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                                   (xmin, ymax)])
            for line in lines:
                line_tmp = LineString([(line[0], line[1]), (line[2], line[3])])
                # line_tmp = LineString([(750, 502), (1035, 502)])
                # decision = [line_tmp.within(box_polygon), line_tmp.contains(box_polygon), line_tmp.overlaps(box_polygon)]
                decision = [
                    line_tmp.within(box_polygon),
                    line_tmp.contains(box_polygon)
                ]
                # attention:[179, 440, 1092, 729]
                # 横线 750, 502, 1035, 509
                if True in decision:
                    lines_tmp1.append(line)
        elif region_box['class_name'] == 'mark':
            coordinates = region_box['bounding_box']
            xmin = coordinates['xmin']
            ymin = coordinates['ymin']
            xmax = coordinates['xmax']
            ymax = coordinates['ymax']
            box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                                   (xmin, ymax)])
            for line in lines:
                line_tmp = LineString([(line[0], line[1]), (line[2], line[3])])
                # line_tmp = LineString([(750, 502), (1035, 502)])
                decision = [
                    line_tmp.within(box_polygon),
                    line_tmp.contains(box_polygon)
                ]
                # attention:[179, 440, 1092, 729]
                # 横线 750, 502, 1035, 509
                if True in decision:
                    lines_tmp1.append(line)
    lines_tmp = [line for line in lines if line not in lines_tmp1]

    # 这里能去掉所有ROI里面的线,下面还要去掉离ROI很远的线,不然遍历费时间
    lines_apart_from_box = []
    for line0 in lines_tmp:
        # 考虑的是点而不是线
        middle_point = [
            1 / 2 * (line0[2] - line0[0]), 1 / 2 * (line0[3] - line0[1])
        ]
        middle_point = list(np.maximum(np.array(middle_point), 0))
        start_point = [line0[0], line0[1]]
        end_point = [line0[2], line0[3]]
        key_point = [middle_point, end_point, start_point]
        for index, region_box in enumerate(sheet_dict):
            if region_box['class_name'] in class_above_edge:
                coordinates = region_box['bounding_box']
                xmin = coordinates['xmin'] - 10
                ymin = coordinates['ymin'] - 10
                xmax = coordinates['xmax'] + 10
                ymax = coordinates['ymax'] + 10
                for pp in key_point:
                    if xmin <= pp[0] <= xmax and ymin <= pp[1] < ymax:
                        lines_apart_from_box.append(line0)

        # line_tmp_ = LineString([(line[0], line[1]), (line[2], line[3])])
        # for index, region_box in enumerate(sheet_dict):
        #     if region_box['class_name'] in class_above_edge:
        #         coordinates = region_box['bounding_box']
        #         xmin = coordinates['xmin'] + 10
        #         ymin = coordinates['ymin'] + 10
        #         xmax = coordinates['xmax'] - 10
        #         ymax = coordinates['ymax'] - 10
        #         box_polygon_ = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)])
        #         decision = [line_tmp_.contains(box_polygon_), line_tmp_.within(box_polygon_),
        #                     line_tmp_.crosses(box_polygon_), line_tmp_.overlaps(box_polygon_)]
        #         if True in decision:
        #             lines_apart_from_box.append(line)
    # 去掉重复线
    lines_apart_from_box_array = np.array(lines_apart_from_box)
    former_one = lines_apart_from_box_array[1:, :]
    rear_one = lines_apart_from_box_array[:-1, :]
    differ = former_one - rear_one
    index_ = sorted(list(set(np.where(differ != 0)[0])))
    lines_apart_from_box_ = [lines_apart_from_box[ele] for ele in index_]
    return lines_apart_from_box_
Beispiel #17
0
def fld_demo4(image, sheet_dict, name, save_path):
    img = Image.fromarray(image)
    t = time.time()
    img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # ret, binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    fld = cv2.ximgproc.createFastLineDetector()
    dlines = fld.detect(img_gray)
    lines = [line[0] for line in dlines.tolist()]

    lines_arr = np.array(lines)
    width_ = lines_arr[:, 2] - lines_arr[:, 0]
    height_ = lines_arr[:, 3] - lines_arr[:, 1]
    lines_index1 = np.where(width_ > 50)[0]
    lines_index2 = np.where(height_ > 50)[0]
    lines_index = np.hstack([lines_index1, lines_index2])
    new_lines = [lines[ele] for ele in lines_index]
    new_lines = clean_repeat_lines(new_lines)
    lines_tmp = filter_long_distance_lines(new_lines, sheet_dict)
    # lines_without_mark = filter_line_in_mark(new_lines, sheet_dict)

    # 检验滤线这一步骤有没有问题
    for dline in lines_tmp:
        x0 = int(round(dline[0]))
        y0 = int(round(dline[1]))
        x1 = int(round(dline[2]))
        y1 = int(round(dline[3]))
        cv2.line(image, (x0, y0), (x1, y1), (0, 255, 0), 1, cv2.LINE_AA)
        text = str([x0, y0, x1, y1])
        cv2.putText(image, text, (x1, y1), cv2.FONT_HERSHEY_COMPLEX, 1,
                    (0, 0, 255), 1)
    write_single_img(image,
                     os.path.join(save_path, name + '_raw_lines' + '.jpg'))

    # get roi polygon 适当放大一点区域,使的线能包含在面里
    roi_box_polygon = []
    for index, region_box in enumerate(sheet_dict):
        if region_box['class_name'] in class_above_edge:
            coordinates = region_box['bounding_box']
            xmin = coordinates['xmin'] - 5
            ymin = coordinates['ymin'] - 5
            xmax = coordinates['xmax'] + 5
            ymax = coordinates['ymax'] + 5
            box_polygon = Polygon([(xmin, ymin), (xmax, ymin), (xmax, ymax),
                                   (xmin, ymax)])
            roi_box_polygon.append(box_polygon)
            cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255), 1)
        cv2.imwrite(r'E:\111_4_26_test_img\aa\save\enlarge_box.jpg', image)

    # print(roi_box_polygon)

    # 对line进行分横向纵向
    landscape_list_tmp = []  # 横向
    longitudinal_list_tmp = []  # 纵向
    for ele in lines_tmp:
        if int(ele[2]) - int(ele[0]) < 10:  # 纵向
            longitudinal_list_tmp.append(ele)
        elif int(ele[3]) - int(ele[1]) < 10:  # 横向
            landscape_list_tmp.append(ele)
    # print(longitudinal_list_tmp)

    points_all_list = []
    points_list = []

    for index, box_polygon in enumerate(roi_box_polygon):
        extend_line_lan = LineString()
        extend_line_lon = LineString()
        # points_list = []
        for line1 in landscape_list_tmp:
            for line2 in longitudinal_list_tmp:
                # 这部分对原先出来的线进行增大
                raw_line_lan = LineString([(line1[0], line1[1]),
                                           (line1[2], line1[3])])  # 横向增加5个像素
                line_start_lan, line_end_lan = raw_line_lan.bounds[
                    0], raw_line_lan.bounds[1]

                raw_line_lon = LineString([(line2[0], line2[1]),
                                           (line2[2], line2[3])])  # 纵向的增加5个像素
                line_start_lon, line_end_lon = raw_line_lon.bounds[
                    0], raw_line_lon.bounds[1]

                # decision1 = [raw_line_lan.within(box_polygon), raw_line_lan.contains(box_polygon), raw_line_lan.overlaps(box_polygon)]
                # decision2 = [raw_line_lon.within(box_polygon), raw_line_lon.contains(box_polygon), raw_line_lon.overlaps(box_polygon)]

                decision1 = [
                    raw_line_lan.within(box_polygon),
                    raw_line_lan.contains(box_polygon)
                ]
                decision2 = [
                    raw_line_lon.within(box_polygon),
                    raw_line_lon.contains(box_polygon)
                ]
                if True in decision1 and True in decision2:
                    # 这里需要考虑延长左边还是右边
                    bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax = box_polygon.bounds[0], box_polygon.bounds[1], \
                                                                 box_polygon.bounds[2], box_polygon.bounds[3]

                    # if abs(line_start_lan - bbox_xmin) < abs(bbox_xmax - line_end_lan):
                    extend_line_lan = LineString([
                        (box_polygon.bounds[0], line1[1]),
                        (box_polygon.bounds[2], line1[3])
                    ])

                    # elif abs(line_start_lon - bbox_ymin) < abs(bbox_ymax - line_end_lon):
                    extend_line_lon = LineString([
                        (line2[0], box_polygon.bounds[1]),
                        (line2[2], box_polygon.bounds[3])
                    ])

                    cond1 = raw_line_lan.intersects(raw_line_lon)
                    cond2 = raw_line_lan.crosses(raw_line_lon)

                    cond3 = extend_line_lan.intersects(extend_line_lon)  # 十字交叉
                    cond4 = extend_line_lan.crosses(extend_line_lon)  # 十字交叉

                    xp, yp = 0.0, 0.0
                    if cond1:
                        (xp, yp
                         ) = raw_line_lan.intersection(raw_line_lon).bounds[:2]
                    elif cond3:
                        (xp, yp) = extend_line_lan.intersection(
                            extend_line_lon).bounds[:2]
                    points_list.append([(xp, yp), (raw_line_lan, raw_line_lon),
                                        (extend_line_lan, extend_line_lon),
                                        box_polygon])

    # TODO 验证找所有点的正确性
    # template = r'F:\exam\sheet_resolve\exam_info\000000-template.xml'
    # tree = ET.parse(template)
    # for ele in points_list:
    #     # for points2 in ele:
    #         # points1 = points_[1][0].bounds
    #         # points2 = points_[1][1].bounds
    #         # create_xml(str(points_[0]), tree, int(points1[0]), int(points1[1]), int(points1[2]), int(points1[3]))
    #         # create_xml(str(points_[0]), tree, int(points2[0]), int(points2[1]), int(points2[2]), int(points2[3]))
    #     points2 = ele[0]
    #     create_xml('points', tree, int(points2[0]), int(points2[1]), int(points2[0] + 1), int(points2[1] + 1))
    # tree.write(os.path.join(save_path, name + '.xml'))

    # 找出角点最优的那个
    # check points   判断点周围有没有黑色像素

    points_list = sorted(points_list, key=lambda k: k[0][0])
    points_all1 = [ele[0] for ele in points_list]
    differ_new1 = np.array(points_all1[1:]) - np.array(points_all1[:-1])
    index_new1 = np.where(differ_new1 > 6.0)[0]
    points_list = [points_list[ele] for ele in index_new1]
    print('points_list:', points_list)
    points_new = []
    for points_ in points_list:
        pixel_point = img.getpixel((int(points_[0][0]), int(points_[0][1])))
        if int(np.mean(np.array(pixel_point))) <= 245:
            points_new.append(points_)
    # print(points_new)

    # 验证这里每个点是不是黑色像素
    template = r'F:\exam\sheet_resolve\exam_info\000000-template.xml'
    tree = ET.parse(template)
    for ele in points_list:
        points2 = ele[0]
        create_xml('points', tree, int(points2[0]), int(points2[1]),
                   int(points2[0] + 1), int(points2[1] + 1))
    tree.write(os.path.join(save_path, 'points_' + name + '.xml'))

    points_new = sorted(points_new, key=lambda k: k[0][0])
    points_new_list = []
    if len(points_new) == 1:
        points_new_list.extend(points_new)
    else:
        points_all_x = [ele[0][0] for ele in points_new]
        rear_one_x = np.array(points_all_x)[1:]
        former_one_x = np.array(points_all_x)[:-1]
        differ_x = rear_one_x - former_one_x
        index_x = list(
            np.where(differ_x >= 6.0)[0])  # 符合条件的说明不是同一个点,这些点都要加进列表里去

        # 头和尾加进去
        # if points_all_x[1] - points_all_x[0] >= 6.0:
        #     index_x.insert(0, 0)
        # elif points_all_x[-1] - points_all_x[-1] >= 6.0:
        #     index_x.append(len(points_all_x) - 1)

        points_all_y = [ele[0][1] for ele in points_new]
        rear_one_y = np.array(points_all_y)[1:]
        former_one_y = np.array(points_all_y)[:-1]
        differ_y = rear_one_y - former_one_y
        index_y = list(
            np.where(differ_y >= 6.0)[0])  # 符合条件的说明不是同一个点,这些点都要加进列表里去

        # 头和尾加进去
        # if points_all_y[1] - points_all_y[0] >= 6.0:
        #     index_y.insert(0, 0)
        # elif points_all_y[-1] - points_all_y[-1] >= 6.0:
        #     index_y.append(len(points_all_y) - 1)

        while len(index_x) == 0 and len(index_y) == 0:  # 说明每个点都不重合,都是需要的点
            points_new_list.extend(points_new)
            break
        if len(index_x) != 0:
            if len(index_x) > 2:
                index_x = list(index_x)
                index_x.insert(0, 0)
                index_x.append(len(points_new))

                for index_a, ele in enumerate(index_x[1:]):
                    block_one = points_new[index_x[index_a]:index_x[index_a +
                                                                    1]]
                    if len(block_one) == 1:
                        points_new_list.extend(block_one)
                    else:
                        # 取均值
                        x_mean = np.mean(
                            np.array([ele[0][0] for ele in block_one]))
                        y_mean = np.mean(
                            np.array([ele[0][1] for ele in block_one]))
                        # 取最长的线

                        # max_index_lan = np.argsort(np.array([int(ele[1][0]) for ele in block_one]))
                        # max_index_lon = np.argsort(np.array([int(ele[1][1]) for ele in block_one]))

                        xx = [int(ele[1][0].length) for ele in block_one]
                        max_index_lan = np.argsort(
                            [int(ele[1][0].length) for ele in block_one])
                        yy = [int(ele[1][1].length) for ele in block_one]
                        max_index_lon = np.argsort(
                            [int(ele[1][1].length) for ele in block_one])
                        zz = block_one[max_index_lan[-1]][1][0]
                        cc = block_one[max_index_lon[-1]][1][1]
                        points_new_list.append([
                            (x_mean, y_mean),
                            (block_one[max_index_lan[-1]][1][0],
                             block_one[max_index_lon[-1]][1][1]),
                            block_one[-1][-1]
                        ])
            print('points_new_list:', points_new_list)
        elif len(index_y) != 0:
            index_y = list(index_y)

            index_y.insert(0, 0)
            index_y.append(len(points_new))

            if len(index_y) > 2:
                for index_a, ele in enumerate(index_y[1:]):
                    block_one = points_new[index_y[index_a]:index_y[index_a +
                                                                    1]]
                    if len(block_one) == 1:
                        points_new_list.extend(block_one)
                    else:
                        # 取均值
                        x_mean = np.mean(
                            np.array([ele[0][0] for ele in block_one]))
                        y_mean = np.mean(
                            np.array([ele[0][1] for ele in block_one]))
                        # 取最长的线

                        # max_index_lan = np.argsort(np.array([int(ele[1][0]) for ele in block_one]))
                        # max_index_lon = np.argsort(np.array([int(ele[1][1]) for ele in block_one]))

                        xx = [int(ele[1][0].length) for ele in block_one]
                        max_index_lan = np.argsort(
                            [int(ele[1][0].length) for ele in block_one])
                        yy = [int(ele[1][1].length) for ele in block_one]
                        max_index_lon = np.argsort(
                            [int(ele[1][1].length) for ele in block_one])
                        zz = block_one[max_index_lan[-1]][1][0]
                        cc = block_one[max_index_lon[-1]][1][1]
                        points_new_list.append([
                            (x_mean, y_mean),
                            (block_one[max_index_lan[-1]][1][0],
                             block_one[max_index_lon[-1]][1][1]),
                            block_one[-1][-1]
                        ])
                print('points_new_list:', points_new_list)
        else:
            points_all_list.extend(points_new)

            # 合并points_new_list成一个list
            # points_new_list_tmp = [ele for ele in points_new_list]

    for points_and_lines in points_new_list:
        direction = get_direction(points_and_lines, points_and_lines[-1],
                                  image)
        if direction != None:
            points_dict = {}
            points_dict['points'] = points_and_lines[0]
            points_dict['direction'] = direction
            points_dict['extend_line'] = points_and_lines[-2]
            points_all_list.append(points_dict)
    print(points_all_list)

    template = r'F:\exam\sheet_resolve\exam_info\000000-template.xml'
    tree = ET.parse(template)
    for points_ in points_all_list:
        points = points_['points']
        create_xml(
            str(points) + '_' + points_['direction'], tree, int(points[0]),
            int(points[1]), int(points[0] + 1), int(points[1] + 1))
    tree.write(os.path.join(save_path, name + '.xml'))
Beispiel #18
0
def compare_range(standard, compare, buf):
    rangement = LineString(standard).buffer(buf)
    compare_line = LineString(compare)
    return rangement.contains(compare_line)
Beispiel #19
0
    hull_pts = hull.exterior.coords.xy

    hull_points = []
    for i in range(0, len(hull_pts[0])):
        hull_points.append((hull_pts[0][i], hull_pts[1][i]))

    polyg = Polygon(hull_points)
    line_polygon = LineString(polyg.exterior.coords)
    # (minx, miny, maxx, maxy)
    bounds = list(map(int, list(polyg.bounds)))
    polni_nivo[_nivo] = []
    outer_nivo[_nivo] = []

    for i in range(bounds[0], bounds[2]+1):
        for j in range(bounds[1], bounds[3]+1):
            if line_polygon.contains(Point(i,j)):
                outer_nivo[_nivo].append((i,j))
            elif polyg.contains(Point(i,j)):
                polni_nivo[_nivo].append((i,j))
                if _nivo == min_z or _nivo == max_z:
                    outer_nivo[_nivo].append((i, j))


with open(f"polninivo{time.time()}.dat", "wb+") as f:
    pickle.dump(polni_nivo, f)

with open(f"outernivo{time.time()}.dat", "wb+") as f:
    pickle.dump(outer_nivo, f)

xdata_final = []
ydata_final = []
def filter_contained_points(line: LineString,
                            points: List[Point]) -> List[Point]:
    return [point for point in points if line.contains(point)]
Beispiel #21
0
                    # Ponto de referência
                    p1 = vertices[p1_num]
                    for m in range(i - nivel_conect * espacamento,
                                   i + nivel_conect * espacamento + 1):
                        if not (0 <= m <= malha_gs.shape[0] - 1):
                            continue
                        for n in range(j - nivel_conect * espacamento,
                                       j + nivel_conect * espacamento + 1):
                            if 0 <= n <= malha_gs.shape[1] - 1:
                                if (p2_num := malha_gs[m, n]) != 0:
                                    # Ponto de comparação
                                    p2 = vertices[p2_num]
                                    if not np.allclose(p1, p2):
                                        linha = LineString([p1, p2])
                                        if not any(
                                                linha.contains(e)
                                                for e in elementos.values()):
                                            if poligono.contains(
                                                    linha
                                            ) or contorno_com_buff.contains(
                                                    linha):
                                                elementos[(p1_num,
                                                           p2_num)] = linha

        return elementos, vertices

    @staticmethod
    def verificar_vertices_ociosos(vertices, elementos) -> tuple:
        # Apagar os vértices que não são utilizados
        verts_usados = []
        for e in elementos:
# Defining the points for the obstacle
obs_pt = [[2, 2], [2, 4], [4, 4], [4, 2]]
obs_poly = Polygon(obs_pt)
plt.gca().add_patch(plt.Polygon(obs_pt, fill=True, color='lightgrey'))

# Inside point
pt_i = [3, 3]
plt.plot(pt_i[0], pt_i[1], 'ok')

# Point on the boundary
pt_b = [2, 3]
plt.plot(pt_b[0], pt_b[1], 'ob')

# Point outside
pt_o = [1, 3]
plt.plot(pt_o[0], pt_o[1], 'or')

# Condition to check if point lies inside polygon
# using polygon.contains(point)
print(obs_poly.contains(Point(pt_i[0], pt_i[1])),
      obs_poly.contains(Point(pt_b[0], pt_b[1])),
      obs_poly.contains(Point(pt_o[0], pt_o[1])))

# Creating a linestring to verify the same
line = LineString(obs_pt)
print(line.contains(Point(pt_i[0], pt_i[1])),
      line.contains(Point(pt_b[0], pt_b[1])),
      line.contains(Point(pt_o[0], pt_o[1])))

plt.show()
Beispiel #23
0
def intersection(x1, y1, x2, y2, x3, y3, x4, y4):
    # wektory
    first_third_x = x3 - x1
    first_third_y = y3 - y1
    rx = x2 - x1
    ry = y2 - y1
    sx = x4 - x3
    sy = y4 - y3

    # obliczanie wyznaczników potrzebnych do wykorzystania metody Cramer'a
    numerator_t = determinant(first_third_x, first_third_y, sx, sy)
    numerator_u = determinant(first_third_x, first_third_y, rx, ry)
    denominator = determinant(rx, ry, sx, sy)

    try:
        t = numerator_t / denominator
        u = numerator_u / denominator

        if denominator != 0 and 0 <= t <= 1 and 0 <= u <= 1:
            i_x = x1 + t * rx
            i_y = y1 + u * ry
            msg = f"Odcinek przecina się w punkcie: ({i_x}, {i_y})"
            messagebox.showinfo('Odpowiedź', msg)
            plot_intersection(x1, y1, x2, y2, x3, y3, x4, y4, i_x, i_y)
        else:
            msg = "Odcninki nie przecinają się oraz nie są równoległe.\nKliknij 'OK', żeby wyświetlić wizualizację."
            messagebox.showinfo('Odpowiedź', msg)
            plot_intersection(x1, y1, x2, y2, x3, y3, x4, y4)

    except ZeroDivisionError:
        if denominator == 0 and numerator_u != 0:
            msg = "Odcinki są równoległe.\nKliknij 'OK', żeby wyświetlić wizualizację."
            messagebox.showinfo('Odpowiedź', msg)
            plot_intersection(x1, y1, x2, y2, x3, y3, x4, y4)

        if numerator_u == 0 and denominator == 0:

            # parametry potrzebne do ocenienia wspólniniowości odcinków
            t_0 = dot_product(first_third_x, first_third_y, rx,
                              ry) / dot_product(rx, ry, rx, ry)
            t_1 = t_0 + dot_product(sx, sy, rx, ry) / dot_product(
                rx, ry, rx, ry)

            # zdefiniowanie punktów oraz odcinków (bibliotek shapely)
            segment_AB = LineString([(x1, y1), (x2, y2)])
            segment_CD = LineString([(x3, y3), (x4, y4)])
            point_A = Point(x1, y1)
            point_B = Point(x2, y2)
            point_C = Point(x3, y3)
            point_D = Point(x4, y4)

            if dot_product(sx, sy, rx, ry) > 0:
                # sprawdzenie czy wyliczone t_0 oraz t_1 mają część wspólną z [0,1]
                interval = portion.closed(t_0, t_1)
                if interval.overlaps(portion.closed(0, 1)):

                    if segment_AB.contains(point_C) and segment_AB.contains(
                            point_D):
                        msg = f"Odcinki są współliniowe i odcinek CD zawiera się w odcinku AB.\n" \
                              f"Przedział wspólny: C({x3}, {y3}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                        messagebox.showinfo('Odpowiedź', msg)
                    elif segment_CD.contains(point_A) and segment_CD.contains(
                            point_B):
                        msg = f"Odcinki są współliniowe i odcinek AB zawiera się w odcinku CD.\n" \
                              f"Przedział wspólny: D({x1}, {y1}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                        messagebox.showinfo('Odpowiedź', msg)

                    elif segment_AB.contains(point_C):
                        if distance.euclidean(point_D,
                                              point_A) > distance.euclidean(
                                                  point_D, point_B):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CB\n" \
                                  f"C({x3}, {y3}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AC\n" \
                                  f"A({x1}, {y1}) - C({x3}, {y3})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_AB.contains(point_D):
                        if distance.euclidean(point_C,
                                              point_A) > distance.euclidean(
                                                  point_C, point_B):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale DB\n" \
                                  f"D({x4}, {y4}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AD\n" \
                                  f"A({x1}, {y1}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_CD.contains(point_A):
                        if distance.euclidean(point_B,
                                              point_C) > distance.euclidean(
                                                  point_B, point_D):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AD\n" \
                                  f"A({x1}, {y1}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CA\n" \
                                  f"C({x3}, {y3}) - A({x1}, {y1})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_CD.contains(point_B):
                        if distance.euclidean(point_A,
                                              point_C) > distance.euclidean(
                                                  point_A, point_D):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale BD\n" \
                                  f"B({x2}, {y2}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CB\n" \
                                  f"C({x3}, {y3}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                else:
                    msg = "Odcinki są współliniowe, ale nie nachodzą na siebie.\nKliknij 'OK', żeby wyświetlić wizualizację."
                    messagebox.showinfo('Odpowiedź', msg)
                plot_intersection(x1, y1, x2, y2, x3, y3, x4, y4)

            if dot_product(sx, sy, rx, ry) < 0:
                interval = portion.closed(t_1, t_0)
                if interval.overlaps(portion.closed(0, 1)):

                    if segment_AB.contains(point_C) and segment_AB.contains(
                            point_D):
                        msg = f"Odcinki są współliniowe i odcinek CD zawiera się w odcinku AB.\n" \
                              f"Przedział wspólny: C({x3}, {y3}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                        messagebox.showinfo('Odpowiedź', msg)
                    elif segment_CD.contains(point_A) and segment_CD.contains(
                            point_B):
                        msg = f"Odcinki są współliniowe i odcinek AB zawiera się w odcinku CD.\n" \
                              f"Przedział wspólny: D({x1}, {y1}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                        messagebox.showinfo('Odpowiedź', msg)

                    elif segment_AB.contains(point_C):
                        if distance.euclidean(point_D,
                                              point_A) > distance.euclidean(
                                                  point_D, point_B):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CB\n" \
                                  f"C({x3}, {y3}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AC\n" \
                                  f"A({x1}, {y1}) - C({x3}, {y3})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_AB.contains(point_D):
                        if distance.euclidean(point_C,
                                              point_A) > distance.euclidean(
                                                  point_C, point_B):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale DB\n" \
                                  f"D({x4}, {y4}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AD\n" \
                                  f"A({x1}, {y1}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_CD.contains(point_A):
                        if distance.euclidean(point_B,
                                              point_C) > distance.euclidean(
                                                  point_B, point_D):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale AD\n" \
                                  f"A({x1}, {y1}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CA\n" \
                                  f"C({x3}, {y3}) - A({x1}, {y1})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)

                    elif segment_CD.contains(point_B):
                        if distance.euclidean(point_A,
                                              point_C) > distance.euclidean(
                                                  point_A, point_D):
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale BD\n" \
                                  f"B({x2}, {y2}) - D({x4}, {y4})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                        else:
                            msg = f"Odcinki są współliniowe i pokrywają się w przedziale CB\n" \
                                  f"C({x3}, {y3}) - B({x2}, {y2})\nKliknij 'OK', żeby wyświetlić wizualizację."
                            messagebox.showinfo('Odpowiedź', msg)
                else:
                    msg = "Odcinki są współliniowe, ale nie nachodzą na siebie.\nKliknij 'OK', żeby wyświetlić wizualizację."
                    messagebox.showinfo('Odpowiedź', msg)
                plot_intersection(x1, y1, x2, y2, x3, y3, x4, y4)
    sys.exit()
Beispiel #24
0
def on_segment(p, q, r):
    line = LineString([Point(p.x, p.y), Point(r.x, r.y)])
    return line.contains(Point(q.x, q.y))
Beispiel #25
0
class Polyline:
    """!
    @brief Custom (open or closed) polyline class
    """
    def __init__(self,
                 coordinates,
                 attributes=None,
                 z_array=None,
                 m_array=None,
                 id=None):
        self._nb_points = len(coordinates)
        self._is_2d = len(coordinates[0]) == 2
        if z_array is not None:
            self._is_2d = False

        self._is_closed = False
        if tuple(coordinates[0]) == tuple(coordinates[-1]):
            self._is_closed = len(
                coordinates
            ) > 2  # line with 2 coordinates which are identical can not be a polygon
            if z_array is not None:
                self._is_closed = z_array[-1] == z_array[0]
        if z_array is None:
            coord = coordinates
        else:
            coord = [(x, y, z) for (x, y), z in zip(coordinates, z_array)]
        if self._is_closed:
            self._polyline = ClosedPolyline(coord)
        else:
            self._polyline = OpenPolyline(coord)
        if attributes is None:
            self._attributes = []
        else:
            self._attributes = attributes[:]

        if m_array is None:
            self.m = [None] * self._nb_points
        else:
            if m_array:
                self.m = m_array[:]
            else:
                self.m = [None] * self._nb_points
        self.id = id

    def set_id(self, id):
        self.id = id

    def to_3d(self, z_array):
        return Polyline(self.coords(), self.attributes(), z_array)

    def to_2d(self):
        if self.is_2d():
            return Polyline(self.coords(), self.attributes(), m_array=self.m)
        return Polyline(list(map(tuple,
                                 np.array(self.coords())[:, :2])),
                        self.attributes(),
                        m_array=self.m)

    def is_2d(self):
        return self._is_2d

    def is_closed(self):
        return self._is_closed

    def nb_points(self):
        return self._nb_points

    def attributes(self):
        return self._attributes

    def add_attribute(self, attribute):
        self._attributes.append(attribute)

    def coords(self):
        if self.is_closed():
            return self._polyline.exterior.coords
        return self._polyline.coords

    def polyline(self):
        return self._polyline

    def project(self, x, y):
        return self._polyline.project(Point(x, y))

    def segments(self):
        prev_x, prev_y = None, None
        for coord in self.coords():
            x, y = coord[:2]  # ignore elevation if 3D
            if prev_x is None:
                prev_x, prev_y = x, y
            else:
                yield x > prev_x, y > prev_y, Polyline([(prev_x, prev_y),
                                                        (x, y)])
                prev_x, prev_y = x, y

    def __str__(self):
        return ['Open', 'Closed'][self.is_closed(
        )] + ' polyline with coordinates %s' % str(list(self.coords()))

    def contains(self, item):
        return self._polyline.contains(item)

    def bounds(self):
        return self._polyline.bounds

    def length(self):
        return self._polyline.length

    def polygon_intersection(self, triangle):
        """!
        @brief (Used in volume calculation) Return the polygon or multipolygon intersection with the triangle
        @param triangle <shapely.geometry.Polygon>: A triangle
        @return <bool, shapely.geometry.Polygon or shapely.geometry.Multipolygon>: The intersection with the triangle
        """
        inter = self._polyline.intersection(triangle)
        if inter.geom_type == 'Polygon' or inter.geom_type == 'MultiPolygon':
            return True, inter
        elif inter.geom_type == 'GeometryCollection':
            poly = list(filter(lambda x: x.geom_type == 'Polygon',
                               inter.geoms))
            if not poly:
                return False, None
            return True, MultiPolygon(poly)
        return False, None

    @staticmethod
    def triangle_difference(triangle, polygon):
        """!
        @brief (Used in volume calculation) Return the polygon or multipolygon in triangle but not in polygon
        @param triangle <shapely.geometry.Polygon>: A triangle
        @param polygon <shapely.geometry.Polygon>: A polygon
        @return <bool, shapely.geometry.Polygon or shapely.geometry.Multipolygon>:
            The difference between triangle and polygon
        """
        diff = triangle.difference(polygon.polyline())
        if diff.geom_type == 'Polygon' or diff.geom_type == 'MultiPolygon':
            return True, diff
        elif diff.geom_type == 'GeometryCollection':
            poly = list(filter(lambda x: x.geom_type == 'Polygon', diff.geoms))
            if not poly:
                return False, None
            return True, MultiPolygon(poly)
        return False, None

    def linestring_intersection(self, triangle):
        """!
        @brief (Used in flux calculation) Returns the LinearString intersection with the triangle
        @param triangle <shapely.geometry.Polygon>: A triangle
        @return <bool, [shapely.geometry.LinearString]>: The intersection with the triangle
        """
        inter = triangle.intersection(self._polyline)
        if inter.geom_type == 'LineString':
            return True, [inter]
        elif inter.geom_type == 'MultiLineString':
            return True, list(inter.geoms)
        elif inter.geom_type == 'GeometryCollection':
            return True, list(
                filter(lambda x: x.geom_type == 'LineString', inter.geoms))
        return False, None

    def apply_transformations(self, transformations):
        new_coords = np.array(list(self.coords()))
        if self.is_2d():
            new_coords = np.hstack((new_coords, np.zeros(
                (self.nb_points(), 1))))

        for t in transformations:
            new_coords = np.apply_along_axis(t, 1, new_coords)
        if self.is_2d():
            new_coords = new_coords[:, :2]

        return Polyline(list(map(tuple, new_coords)),
                        self.attributes(),
                        m_array=self.m)

    def resample(self, max_len):
        new_coords = []
        new_m = []
        coords = list(self.coords())

        new_coords.append(coords[0])
        new_m.append(self.m[0])

        for i in range(self.nb_points() - 1):
            first_point, second_point = coords[i], coords[i + 1]
            segment = OpenPolyline([first_point, second_point])
            nb_segments = int(np.ceil(segment.length / max_len))
            inv_nb_segments = 1 / nb_segments
            first_m, second_m = self.m[i], self.m[i + 1]
            if first_m is None or second_m is None:
                interpolate_m = False
            else:
                interpolate_m = True

            for j in range(1, nb_segments):
                new_point = list(
                    segment.interpolate(j * inv_nb_segments,
                                        normalized=True).coords)[0]
                new_coords.append(new_point)
                if interpolate_m:
                    m = ((1 - j) * first_m + j * second_m) * inv_nb_segments
                    new_m.append(m)
                else:
                    new_m.append(None)
            new_coords.append(second_point)
            new_m.append(second_m)
        return Polyline(new_coords, self.attributes(), m_array=new_m)

    def __repr__(self):
        return "%sPolyline with %i vertices" % ('Closed ' if self.is_closed()
                                                else '', len(self.coords()))
Beispiel #26
0
    def rings2geojson(rings):
        """Check for holes in the ring and fill them."""
        outer_rings = []
        holes = []
        x = None  # iterable
        outer_ring = None  # current outer ring being evaluated
        hole = None  # current hole being evaluated

        for ring in rings:
            if not all(np.isclose(ring[0], ring[-1])):
                ring.append(ring[0])

            if len(ring) < 4:
                continue

            total = sum((pt2[0] - pt1[0]) * (pt2[1] + pt1[1])
                        for pt1, pt2 in zip(ring[:-1], ring[1:]))
            # Clock-wise check
            if total >= 0:
                outer_rings.append([
                    ring[::-1]
                ])  # wind outer rings counterclockwise for RFC 7946 compliance
            else:
                holes.append(
                    ring[::-1]
                )  # wind inner rings clockwise for RFC 7946 compliance

        uncontained_holes = []

        # while there are holes left...
        while holes:
            # pop a hole off out stack
            hole = holes.pop()

            # loop over all outer rings and see if they contain our hole.
            contained = False
            x = len(outer_rings) - 1
            while x >= 0:
                outer_ring = outer_rings[x][0]
                l1, l2 = LineString(outer_ring), LineString(hole)
                p2 = Point(hole[0])
                intersects = l1.intersects(l2)
                contains = l1.contains(p2)
                if not intersects and contains:
                    # the hole is contained push it into our polygon
                    outer_rings[x].append(hole)
                    contained = True
                    break
                x = x - 1

            # ring is not contained in any outer ring
            # sometimes this happens https://github.com/Esri/esri-leaflet/issues/320
            if not contained:
                uncontained_holes.append(hole)

        # if we couldn't match any holes using contains we can try intersects...
        while uncontained_holes:
            # pop a hole off out stack
            hole = uncontained_holes.pop()

            # loop over all outer rings and see if any intersect our hole.
            intersects = False
            x = len(outer_rings) - 1
            while x >= 0:
                outer_ring = outer_rings[x][0]
                l1, l2 = LineString(outer_ring), LineString(hole)
                intersects = l1.intersects(l2)
                if intersects:
                    # the hole is contained push it into our polygon
                    outer_rings[x].append(hole)
                    intersects = True
                    break
                x = x - 1

            if not intersects:
                outer_rings.append([hole[::-1]])

        if len(outer_rings) == 1:
            return {"type": "Polygon", "coordinates": outer_rings[0]}

        return {"type": "MultiPolygon", "coordinates": outer_rings}
Beispiel #27
0
def get_ex_gyms():
    ex_gyms = []
    parks = get_all_parks()
    try:
        ex_gyms = load_pickle('ex_gyms', raise_exception=True)
    except (FileNotFoundError, TypeError, KeyError):
        for g in get_gym_markers():
            g['id'] = 'ex-' + g['id']
            gym_point = Point(g['lat'], g['lon'])
            cell = Polygon(get_s2_cell_as_polygon(g['lat'], g['lon'],
                                                  level=20))  # s2 lvl 20
            sponsor_value = 'park'
            if g['sponsor'] == 7:
                sponsor_value = 'starbucks'
                ex_gyms.append({
                    'id': g['id'],
                    'external_id': g['external_id'],
                    'fort_id': g['fort_id'],
                    'name': g['gym_name'],
                    'lat': g['lat'],
                    'lon': g['lon'],
                    'sponsor': sponsor_value
                })
            if g['sponsor'] == 9:
                sponsor_value = 'sprint'
                ex_gyms.append({
                    'id': g['id'],
                    'external_id': g['external_id'],
                    'fort_id': g['fort_id'],
                    'name': g['gym_name'],
                    'lat': g['lat'],
                    'lon': g['lon'],
                    'sponsor': sponsor_value
                })
            for p in parks:
                coords = p['coords']
                # osm polygon can be a line
                if len(coords) == 2:
                    shape = LineString(coords)
                    if shape.within(cell.centroid):
                        ex_gyms.append({
                            'id': g['id'],
                            'external_id': g['external_id'],
                            'fort_id': g['fort_id'],
                            'name': g['gym_name'],
                            'lat': g['lat'],
                            'lon': g['lon'],
                            'sponsor': sponsor_value
                        })
                if len(coords) > 2:
                    shape = Polygon(coords)
                    if shape.contains(cell.centroid):
                        ex_gyms.append({
                            'id': g['id'],
                            'external_id': g['external_id'],
                            'fort_id': g['fort_id'],
                            'name': g['gym_name'],
                            'lat': g['lat'],
                            'lon': g['lon'],
                            'sponsor': sponsor_value
                        })

        dump_pickle('ex_gyms', ex_gyms)
    return ex_gyms