使用GPS经纬度定位附近地点
数据库中记录了商家在百度标注的经纬度(如:116.412007,39.947545)
最初想法,以圆心点为中心点,对半径做循环,半径每增加一个像素(暂定1米)再对周长做循环,到数据库中查询对应点的商家(真是一个长时间的循环工作),上网百度类似的文章有了点眉目
大致想法是已知一个中心点,一个半径,求圆包含于圆抛物线里所有的点,这样的话就需要知道所要求的这个圆的对角线的顶点,问题来了经纬度是一个点,半径是一个距离,不能直接加减
复制代码代码如下:
//////经纬度坐标///
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;//地球半径(米)
//////角度数转换为弧度公式/////////privatestaticdoubleradians(doubled){returndMath.PI/180.0;}
//////弧度转换为角度数公式/////////privatestaticdoubledegrees(doubled){returnd(180/Math.PI);}
//////计算两个经纬度之间的直接距离///
publicstaticdoubleGetDistance(DegreeDegree1,DegreeDegree2){doubleradLat1=radians(Degree1.X);doubleradLat2=radians(Degree2.X);doublea=radLat1-radLat2;doubleb=radians(Degree1.Y)-radians(Degree2.Y);
doubles=2Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2)+Math.Cos(radLat1)Math.Cos(radLat2)Math.Pow(Math.Sin(b/2),2)));s=sEARTH_RADIUS;s=Math.Round(s10000)/10000;returns;}
//////计算两个经纬度之间的直接距离(google算法)///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=sEARTH_RADIUS;s=Math.Round(s10000)/10000;returns;}
//////以一个经纬度为中心计算出四个顶点//////半径(米)///publicstaticDegree[]GetDegreeCoordinates(DegreeDegree1,doubledistance){doubledlng=2Math.Asin(Math.Sin(distance/(2EARTH_RADIUS))/Math.Cos(Degree1.X));dlng=degrees(dlng);//一定转换成角度数原PHP文章这个地方说的不清楚根本不正确后来lz又查了很多资料终于搞定了
doubledlat=distance/EARTH_RADIUS;dlat=degrees(dlat);//一定转换成角度数
returnnewDegree[www.visa158.com]{newDegree(Math.Round(Degree1.X+dlat,6),Math.Round(Degree1.Y-dlng,6)),//left-topnewDegree(Math.Round(Degree1.X-dlat,6),Math.Round(Degree1.Y-dlng,6)),//left-bottomnewDegree(Math.Round(Degree1.X+dlat,6),Math.Round(Degree1.Y+dlng,6)),//right-topnewDegree(Math.Round(Degree1.X-dlat,6),Math.Round(Degree1.Y+dlng,6))//right-bottom};
}}
测试方法:
复制代码代码如下:
staticvoidMain(string[www.hunanwang.net]args){doublea=CoordDispose.GetDistance(newDegree(116.412007,39.947545),newDegree(116.412924,39.947918));//116.416984,39.944959doubleb=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<>''''ANDdbo.Get_StrArrayStrOfIndex(zuobiao,'','',1)>116.41021ANDdbo.Get_StrArrayStrOfIndex(zuobiao,'','',1)<116.413804ANDdbo.Get_StrArrayStrOfIndex(zuobiao,'','',2)<39.949369ANDdbo.Get_StrArrayStrOfIndex(zuobiao,'','',2)>39.945721
|
|