Example #1
0
 def test_get_pool_pix(self):
     src_point = [114.4314, 30.523558]
     self.baidu_obj = baidu_map.BaiduMap(src_point,
                                         zoom=15,
                                         scale=1,
                                         map_type=baidu_map.MapType.gaode)
     pool_cnts, (pool_cx,
                 pool_cy) = self.baidu_obj.get_pool_pix(b_show=False)
     self.assertIsNot(pool_cnts, None)
Example #2
0
 def test_get_pool_name(self):
     src_point = [114.4314, 30.523558]
     self.baidu_obj = baidu_map.BaiduMap(src_point,
                                         zoom=15,
                                         scale=1,
                                         map_type=baidu_map.MapType.gaode)
     self.baidu_obj.get_pool_name()
     self.assertEqual(type(self.baidu_obj.pool_name), str)
     self.assertEqual(type(self.baidu_obj.address), str)
Example #3
0
 def test_scan_pool(self):
     src_point = [114.4314, 30.523558]
     self.baidu_obj = baidu_map.BaiduMap(src_point,
                                         zoom=15,
                                         scale=1,
                                         map_type=baidu_map.MapType.gaode)
     pool_cnts, (pool_cx,
                 pool_cy) = self.baidu_obj.get_pool_pix(b_show=False)
     scan_cnts = self.baidu_obj.scan_pool(meter_gap=50,
                                          safe_meter_distance=10,
                                          b_show=False)
     self.assertFalse(len(scan_cnts) < 0)
Example #4
0
def get_path(baidu_map_obj=None,
             mode=0,
             target_lng_lats=None,
             target_pixs=None,
             b_show=False,
             back_home=False,
             map_connect=7,
             pix_gap=30):
    """
    根据设置模式返回高德地图上规划路径
    :param baidu_map_obj 地图对象
    :param mode 选择模式
    :param target_lng_lats 目标经纬度集合,传入为高德经纬度
    :param target_pixs 目标像素
    :param b_show 是否显示图像
    :param map_connect 搜索一个点最多连接数量
    :param pix_gap 自动搜索像素间隔
    mode
    0 到达目标点后停留
    1 到达多个目标点
    2 扫描整个湖泊
    4  返航
    """
    global path_matrix
    if baidu_map_obj == None:
        baidu_map_obj = baidu_map.BaiduMap(config.ship_gaode_lng_lat,
                                           zoom=16,
                                           scale=1,
                                           map_type=baidu_map.MapType.gaode)
        pool_cnts, (pool_cx,
                    pool_cy) = baidu_map_obj.get_pool_pix(b_show=False)
        if pool_cnts is None:
            return 'pool_cx is None'
    baidu_map_obj.outpool_cnts_set = get_outpool_set(
        np.array(baidu_map_obj.pool_cnts))

    # 无GPS调试模式 以湖泊中心作为起点
    if config.home_debug:
        baidu_map_obj.ship_gaode_lng_lat = config.ship_gaode_lng_lat
        baidu_map_obj.ship_gps = config.ship_gaode_lng_lat

    if baidu_map_obj.ship_gps is None:
        return 'no ship gps'
    if mode == 0:
        if target_lng_lats is None:
            return 'target_pixs is None'
        elif len(target_lng_lats) > 1:
            return 'len(target_pixs) is >1 choose mode 1'
        if baidu_map_obj.ship_pix is None:
            if baidu_map_obj.ship_gaode_lng_lat is None:
                baidu_map_obj.ship_gaode_lng_lat = baidu_map_obj.gps_to_gaode_lng_lat(
                    baidu_map_obj.ship_gps)
            baidu_map_obj.ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(
                baidu_map_obj.ship_gaode_lng_lat)
        s_start = tuple(baidu_map_obj.ship_pix)
        s_goal = tuple(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lats[0]))
        print('s_start,s_goal', s_start, s_goal)
        # 判断是否能直线到达,不能则采用路径搜索
        if not cross_outpool(s_start, s_goal, baidu_map_obj.pool_cnts):
            try:
                # astar = AStar(s_start, s_goal, "euclidean", baidu_map_obj.outpool_cnts_set)
                # astar_path, visited = astar.searching()
                rrt_conn = RrtConnect(s_start, s_goal, 1, 0.1, 10000,
                                      baidu_map_obj.pool_cnts)
                astar_path = rrt_conn.planning()
                print('astar_path', astar_path)
                return_pix_path = astar_path[::-1]
                # 返航时添加
                if back_home:
                    return_pix_path.append(astar_path)
                print('原始长度', len(return_pix_path))
                return_pix_path = multi_points_to_simple_points(
                    return_pix_path)
                print('简化后长度', len(return_pix_path))
                _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
                    return_pix_path)
                if b_show:
                    baidu_map_obj.show_img = cv2.polylines(
                        baidu_map_obj.show_img,
                        [np.array(astar_path, dtype=np.int32)], False,
                        (255, 0, 0), 1)
                    cv2.circle(baidu_map_obj.show_img, s_start, 5,
                               [255, 0, 255], -1)
                    cv2.circle(baidu_map_obj.show_img, s_goal, 5,
                               [255, 0, 255], -1)
                    baidu_map_obj.show_img = cv2.drawContours(
                        baidu_map_obj.show_img, [return_pix_path], -1,
                        (0, 0, 255), 3)
                    cv2.imshow('scan', baidu_map_obj.show_img)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
                return return_gaode_lng_lat_path
            except Exception as e:
                print('error ', e)
                if b_show:
                    cv2.circle(baidu_map_obj.show_img, s_start, 5, [0, 255, 0],
                               -1)
                    cv2.circle(baidu_map_obj.show_img, s_goal, 5, [0, 0, 255],
                               -1)
                    cv2.imshow('scan', baidu_map_obj.show_img)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
                return 'can not fand path'
        # 直接可达模式
        else:
            return_pix_path = []
            return_pix_path.append(s_start)
            return_pix_path.append(s_goal)
            _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
                return_pix_path)
            if b_show:
                cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 255, 0],
                           -1)
                cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 255, 0],
                           -1)
                baidu_map_obj.show_img = cv2.drawContours(
                    baidu_map_obj.show_img, np.array([return_pix_path]), -1,
                    (0, 0, 255), 3)
                cv2.imshow('scan', baidu_map_obj.show_img)
                cv2.waitKey(0)
                cv2.destroyAllWindows()

            # 返航时添加家的经纬度
            if back_home:
                if config.home_debug:
                    return_gaode_lng_lat_path.append(config.ship_gaode_lng_lat)
                else:
                    return_gaode_lng_lat_path.append(
                        baidu_map_obj.init_ship_gaode_lng_lat)
            return return_gaode_lng_lat_path

    elif mode == 1:
        if target_lng_lats is None:
            return 'target_pixs is None'
        elif len(target_lng_lats) <= 1:
            return 'len(target_pixs) is<=1 choose mode 0'
        if baidu_map_obj.ship_pix is None:
            if baidu_map_obj.ship_gaode_lng_lat is None:
                baidu_map_obj.ship_gaode_lng_lat = baidu_map_obj.gps_to_gaode_lng_lat(
                    baidu_map_obj.ship_gps)
            baidu_map_obj.ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(
                baidu_map_obj.ship_gaode_lng_lat)

        target_pixs = []
        for target_lng_lat in target_lng_lats:
            target_pixs.append(
                baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lat))
        target_pixs.insert(0, baidu_map_obj.ship_pix)
        distance_matrix = measure_distance(target_pixs,
                                           baidu_map_obj.pool_cnts,
                                           baidu_map_obj.outpool_cnts_set,
                                           map_connect=config.find_points_num)
        if back_home:
            tsp_path = solve_tsp(distance_matrix, endpoints=(0, 0))
        else:
            tsp_path = solve_tsp(distance_matrix,
                                 endpoints=(0, (len(target_pixs) - 1)))
        path_points = []
        print('path_matrix', path_matrix)
        for index_i, val in enumerate(tsp_path):
            if index_i < len(tsp_path) - 1:
                if '%d_%d' % (val,
                              tsp_path[index_i + 1]) in path_matrix.keys():
                    path_points.extend(
                        path_matrix['%d_%d' % (val, tsp_path[index_i + 1])])
                elif '%d_%d' % (tsp_path[index_i + 1],
                                val) in path_matrix.keys():
                    path_points.extend(
                        path_matrix['%d_%d' %
                                    (tsp_path[index_i + 1], val)][::-1])
                else:
                    path_points.append(target_pixs[val])
            elif index_i == len(tsp_path) - 1:
                if '%d_%d' % (val, tsp_path[index_i - 1]) in path_matrix.keys(
                ) or '%d_%d' % (val,
                                tsp_path[index_i - 1]) in path_matrix.keys():
                    pass
                else:
                    path_points.append(target_pixs[val])

        return_pix_path = path_points
        print('原始长度', len(return_pix_path))
        return_pix_path = multi_points_to_simple_points(return_pix_path)
        print('简化后长度', len(return_pix_path))

        _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
            return_pix_path)
        if b_show:
            baidu_map_obj.show_img = cv2.polylines(
                baidu_map_obj.show_img,
                [np.array(path_points, dtype=np.int32)], False, (255, 0, 0), 1)
            cv2.imshow('scan', baidu_map_obj.show_img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        return return_gaode_lng_lat_path

    elif mode == 2:
        baidu_map_obj.scan_pool(baidu_map_obj.pool_cnts,
                                pix_gap=pix_gap,
                                b_show=False)
        print('len(scan_cnt)', len(baidu_map_obj.scan_point_cnts))
        distance_matrix = measure_distance(baidu_map_obj.scan_point_cnts,
                                           baidu_map_obj.pool_cnts,
                                           baidu_map_obj.outpool_cnts_set,
                                           map_connect=map_connect)
        tsp_path = solve_tsp(distance_matrix, endpoints=(0, 0))
        print('tsp_path', tsp_path)
        path_points = []
        print('baidu_map_obj.pool_cnts', baidu_map_obj.pool_cnts)
        print('path_matrix', path_matrix)
        print('list path_matrix', list(path_matrix.keys()))
        for index_i, val in enumerate(tsp_path):
            if index_i < len(tsp_path) - 1:
                if '%d_%d' % (val,
                              tsp_path[index_i + 1]) in path_matrix.keys():
                    path_points.extend(
                        path_matrix['%d_%d' % (val, tsp_path[index_i + 1])])
                elif '%d_%d' % (tsp_path[index_i + 1],
                                val) in path_matrix.keys():
                    path_points.extend(
                        path_matrix['%d_%d' %
                                    (tsp_path[index_i + 1], val)][::-1])
                else:
                    path_points.append(baidu_map_obj.scan_point_cnts[val])
            elif index_i == len(tsp_path) - 1:
                if '%d_%d' % (val, tsp_path[index_i - 1]) in path_matrix.keys(
                ) or '%d_%d' % (val,
                                tsp_path[index_i - 1]) in path_matrix.keys():
                    pass
                else:
                    pass
                    # path_points.append(baidu_map_obj.scan_point_cnts[val])
        if b_show:
            baidu_map_obj.show_img = cv2.polylines(
                baidu_map_obj.show_img,
                [np.array(path_points, dtype=np.int32)], False, (255, 0, 0), 1)
            cv2.imshow('scan', baidu_map_obj.show_img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        return_pix_path = path_points
        return_pix_path = path_points
        print('原始长度', len(return_pix_path))
        return_pix_path = multi_points_to_simple_points(return_pix_path)
        print('简化后长度', len(return_pix_path))
        _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
            return_pix_path)
        return return_gaode_lng_lat_path

    elif mode == 3:
        pass

    # back home
    elif mode == 4:
        if baidu_map_obj.init_ship_gps is None:
            return 'ship init gps is None'
        if baidu_map_obj.init_ship_pix is None:
            if baidu_map_obj.init_ship_gaode_lng_lat is None:
                baidu_map_obj.init_ship_gaode_lng_lat = baidu_map_obj.gps_to_gaode_lng_lat(
                    baidu_map_obj.init_ship_gps)
            baidu_map_obj.init_ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(
                baidu_map_obj.init_ship_gaode_lng_lat)

        baidu_map_obj.ship_gaode_lng_lat = baidu_map_obj.gps_to_gaode_lng_lat(
            baidu_map_obj.ship_gps)
        baidu_map_obj.ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(
            baidu_map_obj.ship_gaode_lng_lat)

        s_start = tuple(baidu_map_obj.ship_pix)
        s_goal = tuple(baidu_map_obj.init_ship_pix)
        print('s_start,s_goal', s_start, s_goal)
        # 判断是否能直线到达,不能则采用路径搜索
        if not cross_outpool(s_start, s_goal, baidu_map_obj.pool_cnts):
            rrt_conn = RrtConnect(s_start, s_goal, 1, 0.05, 100000,
                                  baidu_map_obj.pool_cnts)
            astar_path = rrt_conn.planning()
            print('astar_path', astar_path)
            baidu_map_obj.show_img = cv2.polylines(
                baidu_map_obj.show_img, [np.array(astar_path, dtype=np.int32)],
                False, (255, 0, 0), 1)
            return_pix_path = astar_path[::-1]
            return_pix_path = multi_points_to_simple_points(return_pix_path)
            _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
                return_pix_path)
            if b_show:
                cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 0, 255],
                           -1)
                cv2.circle(baidu_map_obj.show_img, s_goal, 5, [0, 0, 255], -1)
                baidu_map_obj.show_img = cv2.drawContours(
                    baidu_map_obj.show_img, [return_pix_path], -1, (0, 0, 255),
                    3)
                cv2.imshow('scan', baidu_map_obj.show_img)
                cv2.waitKey(0)
                cv2.destroyAllWindows()
            return return_gaode_lng_lat_path
            # except:
            #     if b_show:
            #         cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 255, 0], -1)
            #         cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 255, 0], -1)
            #         baidu_map_obj.show_img = cv2.drawContours(baidu_map_obj.show_img, [return_pix_path], -1, (0, 0, 255), 3)
            #
            #         cv2.imshow('scan', baidu_map_obj.show_img)
            #         cv2.waitKey(0)
            #         cv2.destroyAllWindows()
            #         return -3
        # 直接可达模式
        else:
            return_pix_path = []
            return_pix_path.append(s_start)
            return_pix_path.append(s_goal)
            _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(
                return_pix_path)
            if b_show:
                cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 255, 0],
                           -1)
                cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 255, 0],
                           -1)
                cv2.imshow('scan', baidu_map_obj.show_img)
                cv2.waitKey(0)
                cv2.destroyAllWindows()
            return return_gaode_lng_lat_path
    else:
        return 1
Example #5
0
    def find_pool(self):
        while True:
            # 循环等待一定时间
            time.sleep(config.check_status_interval)
            # 若是用户没有点击点
            if self.server_data_obj.mqtt_send_get_obj.pool_click_lng_lat is None or self.server_data_obj.mqtt_send_get_obj.pool_click_zoom is None:
                # self.logger.info('没有点击湖,等待用户执行操作')
                continue

            # 查找与更新湖泊id
            save_img_dir = os.path.join(config.root_path, 'baiduMap', 'imgs')
            if not os.path.exists(save_img_dir):
                os.mkdir(save_img_dir)
            if self.current_map_type == baidu_map.MapType.gaode:
                save_img_path = os.path.join(
                    save_img_dir, 'gaode_%f_%f_%i_%i.png' %
                    (self.server_data_obj.mqtt_send_get_obj.
                     pool_click_lng_lat[0], self.server_data_obj.
                     mqtt_send_get_obj.pool_click_lng_lat[1],
                     self.server_data_obj.mqtt_send_get_obj.pool_click_zoom,
                     1))
            elif self.current_map_type == baidu_map.MapType.tecent:
                save_img_path = os.path.join(
                    save_img_dir, 'tecent_%f_%f_%i_%i.png' %
                    (self.server_data_obj.mqtt_send_get_obj.
                     pool_click_lng_lat[0], self.server_data_obj.
                     mqtt_send_get_obj.pool_click_lng_lat[1],
                     self.server_data_obj.mqtt_send_get_obj.pool_click_zoom,
                     1))
            elif self.current_map_type == baidu_map.MapType.baidu:
                save_img_path = os.path.join(
                    save_img_dir, 'baidu_%f_%f_%i_%i.png' %
                    (self.server_data_obj.mqtt_send_get_obj.
                     pool_click_lng_lat[0], self.server_data_obj.
                     mqtt_send_get_obj.pool_click_lng_lat[1],
                     self.server_data_obj.mqtt_send_get_obj.pool_click_zoom,
                     1))
            # 创建于查找湖泊
            if len(self.data_define_obj.pool_code) <= 0 or not os.path.exists(
                    save_img_path):
                # 创建地图对象
                self.baidu_map_obj = baidu_map.BaiduMap(
                    lng_lat=self.server_data_obj.mqtt_send_get_obj.
                    pool_click_lng_lat,
                    zoom=self.server_data_obj.mqtt_send_get_obj.
                    pool_click_zoom,
                    logger=self.map_log,
                    map_type=self.current_map_type)
                pool_cnts, (pool_cx,
                            pool_cy) = self.baidu_map_obj.get_pool_pix()
                # 为NOne表示没有找到湖泊 继续换地图找
                if pool_cnts is None:
                    if self.current_map_type == baidu_map.MapType.gaode:
                        self.current_map_type = baidu_map.MapType.tecent
                        continue
                    if self.current_map_type == baidu_map.MapType.tecent:
                        self.current_map_type = baidu_map.MapType.baidu
                        continue
                    if self.current_map_type == baidu_map.MapType.baidu:
                        self.current_map_type = baidu_map.MapType.gaode
                        # 若返回为None表示没找到湖 定义错误代码
                        is_collision = 1
                        pool_info_data = {
                            'deviceId':
                            config.ship_code,
                            'lng_lat':
                            self.server_data_obj.mqtt_send_get_obj.
                            pool_click_lng_lat,
                            'is_collision':
                            is_collision,
                            'zoom':
                            self.server_data_obj.mqtt_send_get_obj.
                            pool_click_zoom,
                        }
                        self.send(method='mqtt',
                                  topic='pool_info_%s' % (config.ship_code),
                                  data=pool_info_data,
                                  qos=1)
                        self.logger.debug({'pool_info_data': pool_info_data})
                        continue
                # 获取湖泊轮廓与中心点经纬度位置 _位置为提供前端直接绘图使用

                _, self.baidu_map_obj.pool_lng_lats = self.baidu_map_obj.pix_to_gps(
                    pool_cnts)
                _, self.baidu_map_obj.pool_center_lng_lat = self.baidu_map_obj.pix_to_gps(
                    [[pool_cx, pool_cy]])
                self.logger.info({
                    'pool_center_lng_lat':
                    self.baidu_map_obj.pool_center_lng_lat
                })
                # 判断当前湖泊是否曾经出现,出现过则获取的ID 没出现过发送请求获取新ID
                if isinstance(self.baidu_map_obj.pool_cnts, np.ndarray):
                    save_pool_cnts = self.baidu_map_obj.pool_cnts.tolist()
                else:
                    save_pool_cnts = self.baidu_map_obj.pool_cnts
                send_data = {
                    "longitudeLatitude":
                    json.dumps(self.baidu_map_obj.pool_center_lng_lat),
                    "mapData":
                    json.dumps(self.baidu_map_obj.pool_lng_lats),
                    "deviceId":
                    config.ship_code,
                    "pixData":
                    json.dumps(save_pool_cnts)
                }

                # 本地保存经纬度信息,放大1000000倍 用来只保存整数
                save_pool_lng_lats = [[
                    int(i[0] * 1000000),
                    int(i[1] * 1000000)
                ] for i in self.baidu_map_obj.pool_lng_lats]

                if not os.path.exists(config.local_map_data_path):
                    # 发送请求获取湖泊ID
                    self.logger.debug({'send_data': send_data})
                    try:
                        pool_id = self.send(method='http',
                                            data=send_data,
                                            url=config.http_save,
                                            http_type='POST')
                    except Exception as e:
                        self.logger.error({'error': e})
                        continue
                    if isinstance(self.baidu_map_obj.pool_cnts, np.ndarray):
                        save_pool_cnts = self.baidu_map_obj.pool_cnts.tolist()
                    else:
                        save_pool_cnts = self.baidu_map_obj.pool_cnts
                    save_data = {
                        "mapList": [{
                            "id": pool_id,
                            "pool_center_lng_lat":
                            self.baidu_map_obj.pool_center_lng_lat,
                            "pool_lng_lats": save_pool_lng_lats,
                            "pool_cnts": save_pool_cnts
                        }]
                    }
                    self.logger.info({'pool_id': pool_id})
                    with open(config.local_map_data_path, 'w') as f:
                        json.dump(save_data, f)
                else:
                    with open(config.local_map_data_path, 'r') as f:
                        local_map_data = json.load(f)
                        pool_id = baidu_map.is_in_contours(
                            (self.baidu_map_obj.lng_lat[0] * 1000000,
                             self.baidu_map_obj.lng_lat[1] * 1000000),
                            local_map_data)

                    if pool_id is not None:
                        self.logger.info({'在本地找到湖泊 poolid': pool_id})

                    # 不存在获取新的id
                    else:
                        try:
                            pool_id = self.send(method='http',
                                                data=send_data,
                                                url=config.http_save,
                                                http_type='POST')
                        except Exception as e:
                            self.logger.error({'error': e})
                        self.logger.info({'新的湖泊 poolid': pool_id})
                        with open(config.local_map_data_path, 'w') as f:
                            # 以前存储键值
                            # local_map_data["mapList"].append({"id": pool_id,
                            #                                   "longitudeLatitude": self.baidu_map_obj.pool_center_lng_lat,
                            #                                   "mapData": self.baidu_map_obj.pool_lng_lat,
                            #                                   "pool_cnt": pool_cnts.tolist()})
                            if isinstance(self.baidu_map_obj.pool_cnts,
                                          np.ndarray):
                                save_pool_cnts = self.baidu_map_obj.pool_cnts.tolist(
                                )
                            local_map_data["mapList"].append({
                                "id":
                                pool_id,
                                "pool_center_lng_lat":
                                self.baidu_map_obj.pool_center_lng_lat,
                                "pool_lng_lats":
                                save_pool_lng_lats,
                                "pool_cnts":
                                save_pool_cnts
                            })
                            json.dump(local_map_data, f)

                self.data_define_obj.pool_code = pool_id

                pool_info_data = {
                    'deviceId':
                    config.ship_code,
                    'mapId':
                    self.data_define_obj.pool_code,
                    'lng_lat':
                    self.server_data_obj.mqtt_send_get_obj.pool_click_lng_lat,
                    # 'pool_lng_lats':self.baidu_map_obj.pool_lng_lats
                }
                self.send(method='mqtt',
                          topic='pool_info_%s' % (config.ship_code),
                          data=pool_info_data,
                          qos=1)
                self.logger.info({'pool_info_data': pool_info_data})
Example #6
0
def get_path(baidu_map_obj,
             target_lng_lats,
             b_show=False,
             ):
    """
    根据设置模式返回高德地图上规划路径
    :param baidu_map_obj 地图对象
    :param target_lng_lats 目标经纬度集合,传入为高德经纬度
    :param b_show 是否显示图像
    """
    mode = len(target_lng_lats)
    global path_matrix
    if config.home_debug and baidu_map_obj is None:
        baidu_map_obj = baidu_map.BaiduMap(config.ship_gaode_lng_lat, zoom=16, scale=1,
                                           map_type=baidu_map.MapType.gaode)
        pool_cnts, (pool_cx, pool_cy) = baidu_map_obj.get_pool_pix(b_show=False)
        if pool_cnts is None:
            return 'pool_cx is None'
    if baidu_map_obj.ship_gaode_lng_lat is None:
        return 'no ship gps'

    search_safe_pix = int(config.path_search_safe_distance / baidu_map_obj.pix_2_meter)
    print(config.path_search_safe_distance,baidu_map_obj.pix_2_meter)
    # 单点
    print('mode', mode)
    if mode == 1:
        baidu_map_obj.ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(baidu_map_obj.ship_gaode_lng_lat)

        row_start = tuple(baidu_map_obj.ship_pix)
        row_goal = tuple(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lats[0]))
        s_start = mod_point(row_start)
        s_goal = mod_point(row_goal)
        print('row_start,row_goal ', row_start, row_goal, 's_start,s_goal', s_start, s_goal,)
        print('search_safe_pix', search_safe_pix)
        # 判断是否能直线到达,不能则采用路径搜索
        if not cross_outpool(s_start, s_goal, baidu_map_obj.pool_cnts, search_safe_pix):
            astar = AStar(s_start, s_goal, "euclidean", baidu_map_obj.pool_cnts, search_safe_pix)
            try:
                astar_path, visited = astar.searching()
                return_pix_path = astar_path[::-1]
                simple_return_pix_path = multi_points_to_simple_points(return_pix_path)
                print('原始长度', len(return_pix_path), '简化后长度', len(simple_return_pix_path))
                _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(simple_return_pix_path)
                if b_show:
                    baidu_map_obj.show_img = cv2.polylines(baidu_map_obj.show_img,
                                                           [np.array(astar_path, dtype=np.int32)], False, (255, 0, 0),
                                                           1)
                    cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 0, 255], -1)
                    cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 0, 255], -1)
                    # baidu_map_obj.show_img = cv2.drawContours(baidu_map_obj.show_img, [return_pix_path], -1,
                    #                                           (0, 0, 255), 3)
                    cv2.imshow('scan', baidu_map_obj.show_img)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
                return return_gaode_lng_lat_path
            except Exception as e:
                print('error ', e)
                if b_show:
                    cv2.circle(baidu_map_obj.show_img, s_start, 5, [0, 255, 0], -1)
                    cv2.circle(baidu_map_obj.show_img, s_goal, 5, [0, 0, 255], -1)
                    cv2.imshow('scan', baidu_map_obj.show_img)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
                return 'can not fand path'
        # 直接可达模式
        else:
            return_pix_path = []
            # return_pix_path.append(row_start)
            return_pix_path.append(row_goal)
            _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(return_pix_path)
            if b_show:
                cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 255, 0], -1)
                cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 255, 0], -1)
                baidu_map_obj.show_img = cv2.drawContours(baidu_map_obj.show_img, np.array([return_pix_path]), -1,
                                                          (0, 0, 255), 3)
                cv2.imshow('scan', cv2.resize(baidu_map_obj.show_img, (512, 512)))
                cv2.waitKey(0)
                cv2.destroyAllWindows()
            return return_gaode_lng_lat_path
    # 多点
    else:
        if target_lng_lats is None:
            return 'target_pixs is None'
        elif len(target_lng_lats) <= 1:
            return 'len(target_pixs) is<=1 choose mode 0'
        baidu_map_obj.ship_pix = baidu_map_obj.gaode_lng_lat_to_pix(baidu_map_obj.ship_gaode_lng_lat)
        target_pixs = []
        for target_lng_lat in target_lng_lats:
            target_pixs.append(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lat))
        # 使用TSP优化路径
        if config.b_tsp:
            # 测量距离
            distance_matrix = measure_distance(target_pixs, baidu_map_obj.pool_cnts, map_connect=config.find_points_num)
            tsp_path = solve_tsp(distance_matrix)
            if config.b_tsp:
                tsp_path = solve_tsp(distance_matrix)
            path_points = []
            print('path_matrix', path_matrix)
            for index_i, val in enumerate(tsp_path):
                if index_i < len(tsp_path) - 1:
                    if '%d_%d' % (val, tsp_path[index_i + 1]) in path_matrix.keys():
                        path_points.extend(path_matrix['%d_%d' % (val, tsp_path[index_i + 1])])
                    elif '%d_%d' % (tsp_path[index_i + 1], val) in path_matrix.keys():
                        path_points.extend(path_matrix['%d_%d' % (tsp_path[index_i + 1], val)][::-1])
                    else:
                        path_points.append(target_pixs[val])
                elif index_i == len(tsp_path) - 1:
                    if '%d_%d' % (val, tsp_path[index_i - 1]) in path_matrix.keys() or '%d_%d' % (
                            val, tsp_path[index_i - 1]) in path_matrix.keys():
                        pass
                    else:
                        path_points.append(target_pixs[val])
        else:
            path_points = []
            for index, val in enumerate(target_lng_lats):
                if index == 0:
                    row_start = tuple(baidu_map_obj.ship_pix)
                    row_goal = tuple(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lats[index]))
                else:
                    row_start = tuple(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lats[index - 1]))
                    row_goal = tuple(baidu_map_obj.gaode_lng_lat_to_pix(target_lng_lats[index]))
                s_start = mod_point(row_start)
                s_goal = mod_point(row_goal)
                print('row_start,row_goal', row_start, row_goal, 's_start,s_goal', s_start, s_goal)
                # 判断是否能直线到达,不能则采用路径搜索
                if not cross_outpool(s_start, s_goal, baidu_map_obj.pool_cnts):
                    astar = AStar(s_start, s_goal, "euclidean", baidu_map_obj.pool_cnts, search_safe_pix)
                    try:
                        astar_path, visited = astar.searching()
                        return_pix_path = astar_path[::-1]
                        # simple_return_pix_path = multi_points_to_simple_points(return_pix_path)
                        # print('原始长度', len(return_pix_path), '简化后长度', len(simple_return_pix_path))
                        # _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(simple_return_pix_path)
                        if b_show:
                            baidu_map_obj.show_img = cv2.polylines(baidu_map_obj.show_img,
                                                                   [np.array(astar_path, dtype=np.int32)], False,
                                                                   (255, 0, 0),
                                                                   1)
                            cv2.circle(baidu_map_obj.show_img, s_start, 5, [255, 0, 255], -1)
                            cv2.circle(baidu_map_obj.show_img, s_goal, 5, [255, 0, 255], -1)
                            # baidu_map_obj.show_img = cv2.drawContours(baidu_map_obj.show_img, [return_pix_path], -1,
                            #                                           (0, 0, 255), 3)
                            cv2.imshow('scan', baidu_map_obj.show_img)
                            cv2.waitKey(0)
                            cv2.destroyAllWindows()
                        path_points.extend(return_pix_path)
                    except Exception as e:
                        print('error ', e)
                        if b_show:
                            cv2.circle(baidu_map_obj.show_img, s_start, 5, [0, 255, 0], -1)
                            cv2.circle(baidu_map_obj.show_img, s_goal, 5, [0, 0, 255], -1)
                            cv2.imshow('scan', baidu_map_obj.show_img)
                            cv2.waitKey(0)
                            cv2.destroyAllWindows()
                        path_points.append(row_goal)
                # 直接可达模式
                else:
                    path_points.append(list(row_goal))
        return_pix_path = path_points
        # print('原始长度', len(return_pix_path))
        # return_pix_path = multi_points_to_simple_points(return_pix_path)
        # print('简化后长度', len(return_pix_path))
        _, return_gaode_lng_lat_path = baidu_map_obj.pix_to_gps(return_pix_path)
        if b_show:
            baidu_map_obj.show_img = cv2.polylines(baidu_map_obj.show_img, [np.array(path_points, dtype=np.int32)],
                                                   False, (255, 0, 0), 1)
            cv2.imshow('scan', baidu_map_obj.show_img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        return return_gaode_lng_lat_path
Example #7
0
    def find_pool(self):
        while True:
            # 循环等待一定时间
            time.sleep(0.1)
            for ship_code in server_config.ship_code_list:
                save_map_path = os.path.join(server_config.save_map_dir, 'map_%s.json' % ship_code)
                # 若是用户没有点击点
                if self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat is None or \
                        self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom is None:
                    continue
                # 查找与更新湖泊id
                save_img_dir = os.path.join(config.root_path, 'statics', 'imgs')
                if not os.path.exists(save_img_dir):
                    os.mkdir(save_img_dir)
                # 超过1000张图片时候删除图片
                save_img_name_list = os.listdir(save_img_dir)
                if len(save_img_name_list) > 1000:
                    for i in save_img_name_list:
                        print(os.path.join(save_img_dir, i))
                        os.remove(os.path.join(save_img_dir, i))
                if self.current_map_type == baidu_map.MapType.gaode:
                    save_img_path = os.path.join(
                        save_img_dir, 'gaode_%f_%f_%i_%i.png' %
                                      (self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[0],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[1],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom,
                                       1))
                elif self.current_map_type == baidu_map.MapType.tecent:
                    save_img_path = os.path.join(
                        save_img_dir, 'tecent_%f_%f_%i_%i.png' %
                                      (self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[0],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[1],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom,
                                       1))
                else:
                    save_img_path = os.path.join(
                        save_img_dir, 'baidu_%f_%f_%i_%i.png' %
                                      (self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[0],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat[1],
                                       self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom,
                                       1))
                # 创建于查找湖泊
                if self.data_define_obj_dict.get(ship_code).pool_code or not os.path.exists(save_img_path):
                    # 创建地图对象
                    if os.path.exists(save_img_path) and self.baidu_map_obj_dict.get(ship_code) is not None:
                        continue
                    else:
                        baidu_map_obj = baidu_map.BaiduMap(
                            lng_lat=self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat,
                            zoom=self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom,
                            logger=self.map_log,
                            map_type=self.current_map_type)
                        self.baidu_map_obj_dict.update({ship_code: baidu_map_obj})
                    pool_cnts, (pool_cx, pool_cy) = self.baidu_map_obj_dict.get(ship_code).get_pool_pix()
                    # 为None表示没有找到湖泊 继续换地图找
                    if pool_cnts is None:
                        if self.current_map_type == baidu_map.MapType.gaode:
                            self.current_map_type = baidu_map.MapType.tecent
                            continue
                        if self.current_map_type == baidu_map.MapType.tecent:
                            self.current_map_type = baidu_map.MapType.baidu
                            continue
                        if self.current_map_type == baidu_map.MapType.baidu:
                            self.current_map_type = baidu_map.MapType.gaode
                            # 若返回为None表示没找到湖 定义错误代码
                            is_collision = 1
                            pool_info_data = {
                                'deviceId': ship_code,
                                'lng_lat': self.server_data_obj_dict.get(
                                    ship_code).mqtt_send_get_obj.pool_click_lng_lat,
                                'is_collision': is_collision,
                                'zoom': self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_zoom,
                            }
                            self.send(
                                method='mqtt',
                                topic='pool_info_%s' % ship_code,
                                ship_code=ship_code,
                                data=pool_info_data,
                                qos=1)
                            self.logger.debug({'pool_info_data': pool_info_data})
                            continue
                    # 获取湖泊轮廓与中心点经纬度位置 _位置为提供前端直接绘图使用
                    _, self.baidu_map_obj_dict.get(ship_code).pool_lng_lats = self.baidu_map_obj_dict.get(
                        ship_code).pix_to_gps(pool_cnts)
                    _, self.baidu_map_obj_dict.get(ship_code).pool_center_lng_lat = self.baidu_map_obj_dict.get(
                        ship_code).pix_to_gps([[pool_cx, pool_cy]])
                    self.logger.info(
                        {'pool_center_lng_lat': self.baidu_map_obj_dict.get(ship_code).pool_center_lng_lat})
                    self.baidu_map_obj_dict.get(ship_code).get_pool_name()
                    if self.baidu_map_obj_dict.get(ship_code).pool_name is not None:
                        config.pool_name = self.baidu_map_obj_dict.get(ship_code).pool_name
                    else:
                        config.pool_name = self.baidu_map_obj_dict.get(ship_code).address
                    self.logger.info({'config.pool_name': config.pool_name})
                    # 判断当前湖泊是否曾经出现,出现过则获取的ID 没出现过发送请求获取新ID
                    if isinstance(self.baidu_map_obj_dict.get(ship_code).pool_cnts, np.ndarray):
                        save_pool_cnts = self.baidu_map_obj_dict.get(ship_code).pool_cnts.tolist()
                    else:
                        save_pool_cnts = self.baidu_map_obj_dict.get(ship_code).pool_cnts
                    send_data = {
                        "longitudeLatitude": json.dumps(
                            self.baidu_map_obj_dict.get(ship_code).pool_center_lng_lat),
                        "mapData": json.dumps(
                            self.baidu_map_obj_dict.get(ship_code).pool_lng_lats),
                        "deviceId": ship_code,
                        "name": config.pool_name,
                        "pixData": json.dumps(save_pool_cnts)}

                    # 本地保存经纬度信息,放大1000000倍 用来只保存整数
                    save_pool_lng_lats = [[int(i[0] * 1000000), int(i[1] * 1000000)]
                                          for i in self.baidu_map_obj_dict.get(ship_code).pool_lng_lats]
                    if not os.path.exists(save_map_path):
                        # 发送请求获取湖泊ID
                        self.logger.debug({'send_data': send_data})
                        try:
                            pool_id = self.send(
                                method='http',
                                data=send_data,
                                ship_code=ship_code,
                                url=config.http_save,
                                http_type='POST')
                        except Exception as e:
                            self.logger.error({'error': e})
                            continue
                        if isinstance(self.baidu_map_obj_dict.get(ship_code).pool_cnts, np.ndarray):
                            save_pool_cnts = self.baidu_map_obj_dict.get(ship_code).pool_cnts.tolist()
                        else:
                            save_pool_cnts = self.baidu_map_obj_dict.get(ship_code).pool_cnts
                        save_data = {
                            "mapList": [
                                {
                                    "id": pool_id,
                                    "pool_center_lng_lat": self.baidu_map_obj_dict.get(ship_code).pool_center_lng_lat,
                                    "pool_lng_lats": save_pool_lng_lats,
                                    "pool_cnts": save_pool_cnts}]}
                        self.logger.info({'pool_id': pool_id})
                        with open(save_map_path, 'w') as f:
                            json.dump(save_data, f)
                    else:
                        with open(save_map_path, 'r') as f:
                            local_map_data = json.load(f)
                            pool_id = baidu_map.is_in_contours(
                                (self.baidu_map_obj_dict.get(ship_code).lng_lat[0] * 1000000,
                                 self.baidu_map_obj_dict.get(ship_code).lng_lat[1] * 1000000),
                                local_map_data)
                            print('pool_id', pool_id)
                        if pool_id is not None:
                            self.logger.info({'在本地找到湖泊 poolid': pool_id})
                        # 不存在获取新的id
                        else:
                            try:
                                self.logger.info({config.http_save: send_data})
                                pool_id = self.send(
                                    method='http',
                                    data=send_data,
                                    ship_code=ship_code,
                                    url=config.http_save,
                                    http_type='POST')
                            except Exception as e:
                                # self.logger.info({config.http_save: send_data})
                                self.logger.error({'error': e})
                            self.logger.info({'新的湖泊 poolid': pool_id})
                            with open(save_map_path, 'w') as f:
                                # 以前存储键值
                                # local_map_data["mapList"].append({"id": pool_id,
                                #                                   "longitudeLatitude": self.baidu_map_obj.pool_center_lng_lat,
                                #                                   "mapData": self.baidu_map_obj.pool_lng_lat,
                                #                                   "pool_cnt": pool_cnts.tolist()})
                                if isinstance(self.baidu_map_obj_dict.get(ship_code).pool_cnts, np.ndarray):
                                    save_pool_cnts = self.baidu_map_obj_dict.get(ship_code).pool_cnts.tolist()
                                local_map_data["mapList"].append(
                                    {
                                        "id": pool_id,
                                        "pool_center_lng_lat": self.baidu_map_obj_dict.get(
                                            ship_code).pool_center_lng_lat,
                                        "pool_lng_lats": save_pool_lng_lats,
                                        "pool_cnts": save_pool_cnts})
                                json.dump(local_map_data, f)
                    self.data_define_obj_dict.get(ship_code).pool_code = pool_id
                    pool_info_data = {
                        'deviceId': ship_code,
                        'mapId': self.data_define_obj_dict.get(ship_code).pool_code,
                        'lng_lat': self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.pool_click_lng_lat,
                        # 'pool_lng_lats':self.baidu_map_obj.pool_lng_lats
                    }
                    self.send(
                        method='mqtt',
                        topic='pool_info_%s' %
                              (ship_code),
                        ship_code=ship_code,
                        data=pool_info_data,
                        qos=1)

                    config.write_setting(True)
                    config.update_base_setting()
                    # 在基础设置中发送湖泊名称
                    if self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.b_pool_click:
                        if self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.base_setting_data is None:
                            self.logger.error(
                                {
                                    'base_setting_data is None': self.server_data_obj_dict.get(
                                        ship_code).mqtt_send_get_obj.base_setting_data})
                        else:
                            self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.base_setting_data.update(
                                {'info_type': 3})
                            send_data = self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.base_setting_data
                            send_data.update({'pool_name': config.pool_name})
                            self.send(method='mqtt',
                                      topic='base_setting_%s' % (config.ship_code),
                                      ship_code=ship_code,
                                      data=send_data,
                                      qos=0)
                            self.logger.info({'base_setting': send_data})
                            self.server_data_obj_dict.get(ship_code).mqtt_send_get_obj.b_pool_click = 0