大家知道,天朝的地图都是加偏的,也就是GPS设备接收到的坐标和电子地图坐标是不一样的,有一定的偏移,如果直接把GPS坐标显示到电子地图上,有几百米的误差,必须把GPS坐标加上一定的偏移再显示到电子地图上,才和实际相符,理论上,每种地图偏移量不一样的,且都不是线性的,供应商提供在线的接口,把GPS坐标转换成地图坐标,但算法是保密的,我们可以自己创建纠偏库(参见百度谷歌等地图纠偏库),但部分地方不使用数据库,也不适合网上调用,最合适的办法就是通过算法直接计算,我在网上无意看到了用java写的谷歌地图纠偏算法,稍作修改,变成C#的了,测试了一下,居然腾讯/高德地图纠偏算法也是完全一样,因此,有了该算法,再也不用为纠偏发愁了,不知道该算法是否有泄密的嫌疑,我也是网上抄的,解决了谷歌、腾讯、高德地图纠偏问题,虽然谷歌地图已经谈出视野了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace PostionOffsetCreate
{
public class GDMapOffset
{
private static double pi = 3.14159265358979324;
private static double a = 6378245.0;
private static double ee = 0.00669342162296594323;
public static Point transform(int p_Lng,int p_Lat)
{
double wgLon = 0.000001 * p_Lng, wgLat = 0.000001 * p_Lat;
if (outOfChina(wgLat, wgLon))
{
return new Point(p_Lng, p_Lat);
}
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi;
double magic = Math.Sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.Sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi);
return new Point((int)((wgLon + dLon) * 1000000), (int)((wgLat + dLat) * 1000000));
}
private static bool outOfChina(double lat, double lon)
{
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
private static double transformLat(double x, double y)
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
private static double transformLon(double x, double y)
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
}
}
坐标经纬度均用百万方分之一度表示,返回Point类型,X代表经度,Y代表纬度,即传入GPS坐标,得到地图坐标,如:
Point pt=PostionOffsetCreate. Point transform(120123456,28123456);
无意中发现了谷歌、腾讯、高德地图纠偏算法