设备本身加偏外,电子地图上的坐标也不是真实的,要想正确显示到地图上,还必须将收到的加偏坐标(俗称火星坐标)换算到地图对应的坐标,也就是我们常说的纠偏,而国内用的比较多的地图主要是谷歌和百度,前者有具体的控件,比较好解决,后者就麻烦了,本人这段时间为此事折腾得不轻,但功夫不费有心人,总算比较完美地解决了,故整理一下,给还在或将要受此折腾的人参考。
和大多数人一样,碰到这个问题时,首先想到了百度,总结了百度结果,主要有以下三个方法:
1.使用控件
2.百度地图接口
坐标参数就可以获得对应的地图坐标,该方法优点是方便准确,不足也很明显,受网速、百度服务器等影响,处理大量并发业务时力不从心。
3.数据库
就不亲热了,毕竟我们是个人或小公司嘛,钱不是问题,问题是没钱。
结合起来,巧妙解决了百度地图纠偏问题。
坐标相减得到偏移,将本偏移存放到本地数据库,然后直接返回从百度接口得到的地图坐标。换句话说,我们自己根据车辆使用过的坐标,构建了一个轻量级的数据库,使用一段时间后,我们会发现,绝大部分数据都是从本地数据库获取的,数据量也就区区几十万条而已。
我们分步骤完成这一思路。
第一步:划分区域的算法
,这个数字看起来怪怪的,前面部分表示度,后面部分表示秒,其实也无所谓,反正就是一个区域的唯一标记的特征值而已。为此,我们写一个方法来计算(注意,参数都是百万分之一度)。
参考代码如下:
publicint GetAreaPostion(int GpsCoordinate)
{
nDegree = GpsCoordinate / 1000000 * 1000000;
int nSecond = (int)(0.000001 * (GpsCoordinate – nDegree) * 3600);
return nDegree + nSecond;
}
第二步:创建数据库表
我们需要在数据库里面创建一个表,记录每个区域的偏移量,一个区域包含精确到秒的经度和纬度两列,是唯一的,因此,为直观,我们不妨用中文的“秒经度”、“秒纬度”两列表示,并设置为主键、聚族索引,再增加“经度偏移”、“纬度偏移”、“创建时间”三列,之所以要增加“创建时间”字段,是考虑到时间久了,最好更新一下,比如,半年前的数据最好重新从百度网站取,考虑到速度问题,该字段也需要创建索引。数据库设计界面如下:
第三步:将接收到的GPS坐标转换成对应的区域
坐标包含经度、纬度两部分,因此,我们用Point表示,转换办法参考如下:
MapCorrect map=newMapCorrect();
Point ptArea = new Point(0, 0);
ptArea.X = map.GetAreaPostion(Lng);
ptArea.Y = map.GetAreaPostion(Lat);
第四步:创建数据库访问的方法
既然要访问数据库,必然要提供操作数据库的方法,数据库操作不是本文的重点,大家也都会操作,这里我们创建一个名称为DB的类用于操作数据库,该类主要提供两个静态方法:
GetValueDataRow(string p_strSql)
ExecSql(string p_strSql)
第五步:从数据库查询偏移
为了加快速度和代码更清晰,建议使用存储过程,存储过程代码如下(忽略半年前的数据):
@Lng INT, –精确到秒的经度
@Lat INT –精确到秒的纬度
AS
BEGIN
SET NOCOUNT ON;
SELECT 经度偏移,纬度偏移
FROM dbo.纠偏区域 WITH
WHERE 秒经度=@Lng AND 180
END
第六步:根据查询结果进行处理
如果查询结果中已经有偏移了,直接将偏移和GPS坐标相加,否则,从百度网站查询,并计算偏移然后保存到数据库。
public Point GetMapCoordinate(Point GpsCoordinate)
{
string strSql = string.Format("EXEC GetOffset @Lng ={0},@Lat={1}",
GetAreaPostion(GpsCoordinate.X),
GetAreaPostion(GpsCoordinate.Y));
DataRow row = DB.GetValueDataRow(strSql);
Point ptMap = new Point(0, 0);
if (row == null) //从百度网站查询
{
ptMap = GetFromBaidu(GpsCoordinate);
}
{
ptMap.X = GpsCoordinate.X + (];
ptMap.Y = GpsCoordinate.Y + (];
}
return ptMap;
}
这里,我们需要完成从百度查询坐标的方法,百度网站返回的是JSON数据,JSON很强大,操作方法很多,但这里得到的结果却是简单的一句话:
{"error":0,"x":"MTE5LjE1NzE5NzEwMDc5","y":"MjguMzI0NzUzMTI4NDEz"}
你曾经说,最大的愿望,