关于百度地图分辨率resolution的计算

 

一、名词解释  

  分辨率(resolution,港台称之为解析度)就是屏幕图像的精密度,是指显示器所能显示的像素的多少。由于屏幕上的点、线和面都是由像素组成的,显示器可显示的像素越多,画面就越精细,同样的屏幕区域内能显示的信息也越多,所以分辨率是个非常重要的性能指标之一。(百度百科)

  而地面分辨率是以一个像素(pixel)代表的地面尺寸(米)。

二、百度地图坐标概述

  百度地图使用经纬度地理坐标(lng, lat)和像素坐标(x, y)两种,同时百度api提供两种坐标转换的方法

  经纬度转换为地理坐标的方法为:

方法     返回值描述    
pointToPixel(point:Point)   Pixel                             经纬度坐标转换为像素坐标。

  地理坐标转换为经纬度的方法为:

方法返回值描述
pixelToPoint(pixel:Pixel)Point像素坐标转换为经纬度坐标。

 

------------------------------------------------

 

  博主经营一家发饰淘宝店,都是纯手工制作哦,开业冲钻,只为信誉!需要的亲们可以光顾一下!谢谢大家的支持!
店名:
  小鱼尼莫手工饰品店
经营:
  发饰、头花、发夹、耳环等(手工制作)
网店:
  http://shop117066935.taobao.com/

 

  ---------------------------------------------------------------------

 

继续正题... 

 

  


三、分辨率计算方法

  a) 分辨率与地图比例尺之间换算方法:

                

    Scale:地图比例尺;

    Resolution:地图分辨率;

    PPI:每英寸的像素点数。

    具体参考文章: http://www.cnblogs.com/qiongmiaoer/archive/2013/03/13/2958288.html

  b) 分辨率根据定义( 实际距离/像素值 ),在大比例尺地图下可以近似的用此方法进行计算,就不考虑地球形状因素了,计算方法为:

     分辨率res = (lng1-lng2)/ (x1-x2);

    或 res = (lat1-lat2)/(y1-y1);

四、一般地图中分辨率特性

  同级别地图中分辨率是固定值,因而无论使用经度还是纬度计算,结果都是不变的。

五、百度地图中分辨率特性

  同级别地图中百度分辨率不是固定值,且经度方向,纬度方向变化幅度也不相同,可以通过以下方法测试:  

  var bounds = map.getBounds();               //假设定义好了百度地图为map     
   var geoPointLB = bounds.getSouthWest();    //左下角点地理坐标
   var geoPointRT = bounds.getNorthEast();    //右上角点地理坐标
   var pixelPointLB = BaiduMap.map.pointToPixel(geoPointLB);  //左下角点像素坐标
   var pixelPointRT = BaiduMap.map.pointToPixel(geoPointRT);  //右上角点像素坐标
  
  var resX = (geoPointRT.lng - geoPointLB.lng) / (pixelPointRT.x - pixelPointLB.x);    //分辨率 = 经度差 / x差
  var resY = (geoPointRT.lat - geoPointLB.lat) / (pixelPointRT.y - pixelPointLB.y);    //分辨率 = 纬度差 / y差

  测试结果:resX和resY是不同的。

  原因:百度地图为了数据保密做的一些“纠正”,防止一些不法用途。

  目前解决方案:将百度地图分为经度方向分辨率、纬度方向分辨率,可以一定程度上减小误差,具体实现方法同上方代码示例。 

 

店名:
  小鱼尼莫手工饰品店
经营:
  发饰、头花、发夹、耳环等(手工制作)
网店:
  http://shop117066935.taobao.com/

<think>好的,我现在需要帮用户解决在ROS中使用C++订阅/map话题,获取地图尺寸、原点和分辨率的问题。首先,我得回忆一下ROS中导航相关的消息类型。用户提到的/map话题通常发布的是nav_msgs/OccupancyGrid类型的数据,对吧?所以,我需要确认这个消息的结构。 地图分辨率应该是OccupancyGrid的info.resolution字段,这个字段表示每个栅格的单位,比如米/像素。原点的话,是info.origin,它是一个geometry_msgs/Pose类型,包含了位置和方向。原点的位置应该是相对于机器人建图时的起点,比如x、y、z坐标,而方向可能涉及旋转,不过用户可能只需要位置部分。 地图的尺寸,应该由info.width和info.height给出,分别表示地图的宽度和高度,单位是栅格的数量。所以地图的实际物理尺寸就是宽度乘以分辨率,高度乘以分辨率。 接下来,用户需要用C++实现一个订阅者。步骤大概是:初始化ROS节点,创建订阅者,回调函数处理消息。在回调函数里,提取所需的字段。 需要注意的是,回调函数只会被调用一次吗?不一定,因为/map可能只发布一次,但程序应该持续等待直到收到消息。可能需要使用ros::spinOnce()或者spin()来确保接收到数据。或者用户可能希望程序在收到一次消息后处理并退出?不过通常ROS节点是持续运行的。 在代码结构方面,首先包含必要的头文件,比如ros/ros.h,nav_msgs/OccupancyGrid.h,geometry_msgs/Pose.h。然后定义回调函数,参数是OccupancyGrid的常量指针。在回调里,访问info.resolution,info.width,info.height,以及info.origin.position.x等。 然后主函数里初始化节点,创建订阅者,然后进入循环处理回调。可能需要处理只接收一次的情况,但通常ROS节点会一直运行,除非有特殊要求。 此外,需要注意线程安全,如果数据在回调外使用,可能需要加锁,但如果是简单的打印信息,直接在回调里处理即可。用户可能只需要在回调触发时打印这些信息。 测试的时候,用户需要确保有节点发布/map话题,比如运行地图服务器或者SLAM节点。可能还需要检查坐标系等信息是否正确。 可能的错误点:消息类型是否正确,字段名称是否正确,比如是否拼写正确。例如,info是MapMetaData类型,里面的origin是geometry_msgs/Pose类型,所以正确的访问方式是msg->info.origin.position.x等。 所以,最终的代码示例应该包括订阅/map,在回调中提取这些字段并打印出来。用户可能需要将这些信息保存到变量中以供后续处理,但根据问题描述,主要是获取这些值,所以打印即可。 总结步骤: 1. 包含必要的头文件。 2. 编写回调函数,提取resolution、width、height、origin的x和y。 3. 主函数中初始化ROS,创建订阅者,spin等待消息。 4. 处理可能的一次性接收情况,或者持续运行。</think>在ROS中获取地图信息可通过订阅`/map`话题实现。该话题类型为`nav_msgs/OccupancyGrid`,以下是C++实现步骤: --- ### 1. 创建订阅者节点 ```cpp #include <ros/ros.h> #include <nav_msgs/OccupancyGrid.h> // 定义回调函数 void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg) { // 获取地图分辨率 float resolution = msg->info.resolution; ROS_INFO("地图分辨率: %.3f m/像素", resolution); // 获取地图尺寸(单位:像素) int width = msg->info.width; int height = msg->info.height; ROS_INFO("地图尺寸: %d x %d 像素", width, height); // 获取物理尺寸(单位:米) float physical_width = width * resolution; float physical_height = height * resolution; ROS_INFO("物理尺寸: %.2f m x %.2f m", physical_width, physical_height); // 获取原点坐标 float origin_x = msg->info.origin.position.x; float origin_y = msg->info.origin.position.y; ROS_INFO("地图原点坐标: (%.2f, %.2f)", origin_x, origin_y); } int main(int argc, char** argv) { ros::init(argc, argv, "map_info_subscriber"); ros::NodeHandle nh; // 创建订阅者 ros::Subscriber sub = nh.subscribe("/map", 1, mapCallback); // 进入循环等待回调 ros::spin(); return 0; } ``` --- ### 2. 关键参数说明 1. **分辨率 (`resolution`)** - 类型:`float` - 含义:每个栅格代表的实际距离(米/像素) - 访问路径:`msg->info.resolution` 2. **地图尺寸** - 宽度:`msg->info.width`(像素数量) - 高度:`msg->info.height`(像素数量) 3. **原点 (`origin`)** - 类型:`geometry_msgs/Pose` - 坐标访问路径: ```cpp msg->info.origin.position.x // X坐标 msg->info.origin.position.y // Y坐标 ``` --- ### 3. 编译配置(CMakeLists.txt) ```cmake find_package(catkin REQUIRED COMPONENTS roscpp nav_msgs ) add_executable(map_info_subscriber src/map_info_subscriber.cpp) target_link_libraries(map_info_subscriber ${catkin_LIBRARIES}) ``` --- ### 4. 运行验证 1. 启动地图服务器或SLAM节点(如加载已有地图): ```bash rosrun map_server map_server my_map.yaml ``` 2. 运行订阅者节点: ```bash rosrun your_pkg map_info_subscriber ``` 3. 输出示例: ``` [ INFO] [1620000000.000]: 地图分辨率: 0.050 m/像素 [ INFO] [1620000000.000]: 地图尺寸: 3840 x 3840 像素 [ INFO] [1620000000.000]: 物理尺寸: 192.00 m x 192.00 m [ INFO] [1620000000.000]: 地图原点坐标: (-10.00, -5.00) ``` --- ### 注意事项 1. **坐标系**:原点通常位于地图左下角,符合图像坐标系惯例 2. **数据有效性**:建议添加空指针检查确保`msg->info`有效 3. **单次触发**:若需只处理一次消息,可在回调内添加`ros::shutdown()`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值