数据库中记录了商家在百度标注的经纬度(如:116.412007,39.947545)
最初想法,以圆心点为中心点,对半径做循环,半径每增加一个像素(暂定1米)再对周长做循环,到数据库中查询对应点的商家(真是一个长时间的循环工作),上网百度类似的文章有了点眉目
大致想法是已知一个中心点,一个半径,求圆包含于圆抛物线里所有的点,这样的话就需要知道所要求的这个圆的对角线的顶点,问题来了经纬度是一个点,半径是一个距离,不能直接加减
代码如下:
///<summary>
///经纬度坐标
///</summary>
publicclassDegree
{
publicDegree(doublex,doubley)
{
X=x;
Y=y;
}
privatedoublex;
publicdoubleX
{
get{returnx;}
set{x=value;}
}
privatedoubley;
publicdoubleY
{
get{returny;}
set{y=value;}
}
}
publicclassCoordDispose
{
privateconstdoubleEARTH_RADIUS=6378137.0;//地球半径(米)
///<summary>
///角度数转换为弧度公式
///</summary>
///<paramname=”d”></param>
///<returns></returns>
privatestaticdoubleradians(doubled)
{
returnd*Math.PI/180.0;
}
///<summary>
///弧度转换为角度数公式
///</summary>
///<paramname=”d”></param>
///<returns></returns>
privatestaticdoubledegrees(doubled)
{
returnd*(180/Math.PI);
}
///<summary>
///计算两个经纬度之间的直接距离
///</summary>
publicstaticdoubleGetDistance(DegreeDegree1,DegreeDegree2)
{
doubleradLat1=radians(Degree1.X);
doubleradLat2=radians(Degree2.X);
doublea=radLat1-radLat2;
doubleb=radians(Degree1.Y)-radians(Degree2.Y);
doubles=2*Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2)+
Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2)));
s=s*EARTH_RADIUS;
s=Math.Round(s*10000)/10000;
returns;
}
///<summary>
///计算两个经纬度之间的直接距离(google算法)
///</summary>
publicstaticdoubleGetDistanceGoogle(DegreeDegree1,DegreeDegree2)
{
doubleradLat1=radians(Degree1.X);
doubleradLng1=radians(Degree1.Y);
doubleradLat2=radians(Degree2.X);
doubleradLng2=radians(Degree2.Y);
doubles=Math.Acos(Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Cos(radLng1-radLng2)+Math.Sin(radLat1)*Math.Sin(radLat2));
s=s*EARTH_RADIUS;
s=Math.Round(s*10000)/10000;
returns;
}
///<summary>
///以一个经纬度为中心计算出四个顶点
///</summary>
///<paramname=”distance”>半径(米)</param>
///<returns></returns>
publicstaticDegree[]GetDegreeCoordinates(DegreeDegree1,doubledistance)
{
doubledlng=2*Math.Asin(Math.Sin(distance/(2*EARTH_RADIUS))/Math.Cos(Degree1.X));
dlng=degrees(dlng);//一定转换成角度数 原PHP文章这个地方说的不清楚根本不正确后来lz又查了很多资料终于搞定了
doubledlat=distance/EARTH_RADIUS;
dlat=degrees(dlat);//一定转换成角度数
returnnewDegree[]{newDegree(Math.Round(Degree1.X+dlat,6),Math.Round(Degree1.Y-dlng,6)),//left-top
newDegree(Math.Round(Degree1.X-dlat,6),Math.Round(Degree1.Y-dlng,6)),//left-bottom
newDegree(Math.Round(Degree1.X+dlat,6),Math.Round(Degree1.Y+dlng,6)),//right-top
newDegree(Math.Round(Degree1.X-dlat,6),Math.Round(Degree1.Y+dlng,6))//right-bottom
};
}
}
测试方法:
代码如下:
staticvoidMain(string[]args)
{
doublea=CoordDispose.GetDistance(newDegree(116.412007,39.947545),newDegree(116.412924,39.947918));//116.416984,39.944959
doubleb=CoordDispose.GetDistanceGoogle(newDegree(116.412007,39.947545),newDegree(116.412924,39.947918));
Degree[]dd=CoordDispose.GetDegreeCoordinates(newDegree(116.412007,39.947545),102);
Console.WriteLine(a+””+b);
Console.WriteLine(dd[0].X+”,”+dd[0].Y);
Console.WriteLine(dd[3].X+”,”+dd[3].Y);
Console.ReadLine();
}
试了很多次误差在1米左右
拿到圆的顶点就好办了
数据库要是sql2008的可以直接进行空间索引经纬度字段,这样应该性能更好(没有试过)
lz公司数据库还老2005的这也没关系,关键是经纬度拆分计算,这个就不用说了网上多的是最后上个实现的sql语句
代码如下:
SELECTid,zuobiaoFROMdbo.zuobiaoWHEREzuobiao<>”AND
dbo.Get_StrArrayStrOfIndex(zuobiao,’,’,1)>116.41021AND
dbo.Get_StrArrayStrOfIndex(zuobiao,’,’,1)<116.413804AND
dbo.Get_StrArrayStrOfIndex(zuobiao,’,’,2)<39.949369AND
dbo.Get_StrArrayStrOfIndex(zuobiao,’,’,2)>39.945721
C++设计模式之外观模式
C++中的类型转换static_cast、dynamic_cast、const_cast和reinterpret_cast上述就是C#学习教程:使用GPS经纬度定位附近地点(某一点范围内查询)分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/905151.html