【转】C# 使用Google API进行手机基站定位资料整理

转自:http://www.cnblogs.com/MyLucifer/archive/2010/02/25/1673587.html

 

 

在网上收集了一部分关于使用Google API进行手机定位的资料和大家分享:

 关于基站定位方面的介绍:

http://tech.c114.net/164/a140837.html

开发方面的帮助:

http://www.dotblogs.com.tw/kylin/archive/2009/08/09/9964.aspx

http://code.google.com/intl/zh-CN/apis/maps/documentation/staticmaps/

http://www.codeproject.com/KB/mobile/DeepCast.aspx

http://heresy.spaces.live.com/blog/cns!E0070FB8ECF9015F!7866.entry?wa=wsignin1.0&sa=334916734

以上方法的流程一般如下:

通过RIL获取CellTowerInfo----->通过google api获取经纬度------->转换成54或是地方坐标后在地图上显示位置

 

本人整理了代码进行了测试,效果不是很好,使用的多普达S700,windows mobile 专业版 6.1 ,地点在上海,

定位结果如下

CELLID=1346
LAC=43060
MCC=460
MNC=0

从google获取的坐标31.109,121.368,定位位置到了莘西路上

经过计算与实际位置直线距离在8KM左右

 

而通过Google Maps在手机上测试当前位置提示精度为18000m,呵呵,这个精度恐怕只能确定在那个城市了,个人认为:原因可能有以下几点:

1.周围基站分布较少或是真的很远,上海的移动2G基站每年的数量都在减少,有时在公司的时候都会出现盲区,信号不是很好

2.直接通过cellid,lac,mcc,mnc等信息在Google上获取的经纬度没有经过误差分析,没有太大的精度可言

3.绕开中国移动运营商进行手机基站定位比较难,人家要靠这个赚钱的,当然也牵涉到国家安全,呵呵

4.RIL相关函数严格来说在Windows Mobile 上面都不是必须被实现的

下面是我的代码和注释,有些地方还是不能理解:

 

  1      public   class  RIL
  2      {
  3           // CellTower信息
  4           private   static   string  celltowerinfo  =   "" ;
  5 
  6           // 通过RIL获取CellID
  7           public   static   string  GetCellTowerInfo()
  8          {
  9               // 初始化句柄
 10              IntPtr hRil  =  IntPtr.Zero;
 11              IntPtr hRes  =  IntPtr.Zero;
 12 
 13               // 初始化结果变量
 14              celltowerinfo  =   "" ;
 15 
 16               // 为一个Client初始化RIL    
 17              hRes  =  RIL_Initialize( 1 ,
 18                                  new  RILRESULTCALLBACK(rilResultCallBack),
 19                                  null ,
 20                                  0 ,
 21                                  0 ,
 22                                  out  hRil);
 23 
 24               if  (hRes  !=  IntPtr.Zero)
 25              {
 26                   return   " 不能初始化RIL " ;
 27              }
 28 
 29               // 获取当前Phone使用的基站信息
 30              hRes  =  RIL_GetCellTowerInfo(hRil);
 31 
 32              waithandle.WaitOne();
 33 
 34               // 解除RIL
 35              RIL_Deinitialize(hRil);
 36 
 37               return  celltowerinfo;
 38 
 39 
 40          }
 41 
 42           private   static  AutoResetEvent waithandle  =   new  AutoResetEvent( false );
 43 
 44           public   static   void  rilResultCallBack( uint  dwCode, 
 45                                               IntPtr hrCmdID, 
 46                                               IntPtr lpData, 
 47                                                uint  cdData, 
 48                                                uint  dwParam)
 49          {
 50              RILCELLTOWERINFO rilCellTowerInfo  =   new  RILCELLTOWERINFO();
 51 
 52               // 将数据lpData从非托管内存块封送到rilCellTowerInfo托管对象中
 53              Marshal.PtrToStructure(lpData, rilCellTowerInfo);
 54 
 55              celltowerinfo  =  rilCellTowerInfo.dwCellID  +   " - "   +  rilCellTowerInfo.dwLocationAreaCode  +   " - "   +
 56                              rilCellTowerInfo.dwMobileCountryCode + " - " + rilCellTowerInfo.dwMobileNetworkCode;
 57                 
 58               // 将事件状态设置为终止状态,允许一个或多个等待线程继续
 59              waithandle.Set();
 60          }
 61          
 62           public   delegate   void  RILRESULTCALLBACK( uint  dwCode,IntPtr hrCmdID,IntPtr lpData, uint  cbData, uint  dwParam);
 63 
 64           public   delegate   void  RILNOTIFYCALLBACK( uint  dwCode,IntPtr lpData, uint  cbData, uint  dwParam);
 65 
 66           // RIL基站信息类
 67           public   class  RILCELLTOWERINFO
 68          {
 69                  public   uint  cbSize;  
 70                  public   uint  dwParams;  
 71                  public   uint  dwMobileCountryCode;  
 72                  public   uint  dwMobileNetworkCode;  
 73                  public   uint  dwLocationAreaCode;  
 74                  public   uint  dwCellID;  
 75                  public   uint  dwBaseStationID;  
 76                  public   uint  dwBroadcastControlChannel;  
 77                  public   uint  dwRxLevel;  
 78                  public   uint  dwRxLevelFull;  
 79                  public   uint  dwRxLevelSub;  
 80                  public   uint  dwRxQuality;  
 81                  public   uint  dwRxQualityFull;  
 82                  public   uint  dwRxQualitySub;  
 83                  public   uint  dwIdleTimeSlot;  
 84                  public   uint  dwTimingAdvance;  
 85                  public   uint  dwGPRSCellID;  
 86                  public   uint  dwGPRSBaseStationID;  
 87                  public   uint  dwNumBCCH;  
 88 
 89 
 90          }
 91 
 92           /*  调用API    
 93           * 初始化RIL    
 94           * MSDN:    http://msdn.microsoft.com/zh-cn/library/aa919106 (en-us).aspx  */
 95          [DllImport( " ril.dll " )]
 96           private   static   extern  IntPtr RIL_Initialize( uint  dwIndex, RILRESULTCALLBACK pfnResult, RILNOTIFYCALLBACK pfnNotify,  uint  dwNotificationClasses,  uint  dwParam,  out  IntPtr lphRil);
 97          [DllImport( " ril.dll " )]
 98           private   static   extern  IntPtr RIL_GetCellTowerInfo(IntPtr hRil);
 99          [DllImport( " ril.dll " )]
100           private   static   extern  IntPtr RIL_Deinitialize(IntPtr hRil);
101 
102      }

 

之后是有关通信方面的,通过基站信息获取经纬度(GOOGLE API)

 

代码

 

下面在介绍一种只要知道cellid和lac两个参数就可以获取经纬度的方法:

 

 1    ///   <summary>
 2           ///  判断是否正确获取经纬度信息
 3           ///   </summary>
 4           ///   <param name="cellid"> cellid </param>
 5           ///   <param name="lac"> LocationAreaCode </param>
 6           ///   <param name="Lat"> latitude </param>
 7           ///   <param name="Lng"> longgitude </param>
 8           ///   <returns></returns>
 9           public   static   bool  LocateGooleMapApi( uint  cellid,  uint  lac,  out   double  Lat,  out   double  Lng)
10          {
11              HttpWebRequest request  = (HttpWebRequest)WebRequest.Create( " http://www.google.com/glm/mmap " );
12              request.Method  =   " POST " ;
13 
14           
15               byte [] byteArray  =  { 0x00 , 0x15 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 
16                           0x65 ,  0x6E ,  //  en
17                           0x00 ,  0x07 , 
18                           0x41 ,  0x6E ,  0x64 ,  0x72 ,  0x6F ,  0x69 ,  0x64 , 
19                           0x00 ,  0x03 , 
20                           0x31 ,  0x2E ,  0x30 ,  //  1.0
21                           0x00 ,  0x03 , 
22                           0x57 ,  0x65 ,  0x62 ,  //  web
23                           0x1B , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
24                           0x00 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 
25                           0xFF ,  0xFF ,  0xFF ,  0xFF ,  //  CellID
26                           0xFF ,  0xFF ,  0xFF ,  0xFF ,  //  LAC
27                           0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
28                           0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00  };
29 
30               //  write CellID
31               byte [] intByte  =  BitConverter.GetBytes(cellid);
32              byteArray[ 48 ]  =  intByte[ 3 ];
33              byteArray[ 49 ]  =  intByte[ 2 ];
34              byteArray[ 50 ]  =  intByte[ 1 ];
35              byteArray[ 51 ]  =  intByte[ 0 ];
36 
37               //  write LAC
38              intByte  =  BitConverter.GetBytes(lac);
39              byteArray[ 52 ]  =  intByte[ 3 ];
40              byteArray[ 53 ]  =  intByte[ 2 ];
41              byteArray[ 54 ]  =  intByte[ 1 ];
42              byteArray[ 55 ]  =  intByte[ 0 ];
43 
44               //  set request
45              request.ContentLength  =  byteArray.Length;
46              Stream postStream  =  request.GetRequestStream();
47              postStream.Write(byteArray,  0 , byteArray.Length);
48              postStream.Close();
49 
50               //  Get the response.
51              HttpWebResponse response  =  (HttpWebResponse)request.GetResponse();
52              Console.WriteLine( " [I] Request response: {0} " , response.StatusDescription);
53 
54               //  Read response
55              Stream dataStream  =  response.GetResponseStream();
56              BinaryReader BR  =   new  BinaryReader(dataStream);
57               //  skip 3 byte
58              BR.ReadByte();
59              BR.ReadByte();
60              BR.ReadByte();
61 
62               //  check state
63               if  ( 0   ==  BR.ReadInt32())
64              {
65                   //  read lat
66                   byte [] tmpByte  =   new   byte [ 4 ];
67                  tmpByte[ 3 ]  =  BR.ReadByte();
68                  tmpByte[ 2 ]  =  BR.ReadByte();
69                  tmpByte[ 1 ]  =  BR.ReadByte();
70                  tmpByte[ 0 ]  =  BR.ReadByte();
71                  Lat  =  ( double )(BitConverter.ToInt32(tmpByte,  0 ))  /  1000000D;
72 
73                   //  read lng
74                  tmpByte[ 3 ]  =  BR.ReadByte();
75                  tmpByte[ 2 ]  =  BR.ReadByte();
76                  tmpByte[ 1 ]  =  BR.ReadByte();
77                  tmpByte[ 0 ]  =  BR.ReadByte();
78                  Lng  =  ( double )(BitConverter.ToInt32(tmpByte,  0 ))  /  1000000D;
79 
80                  BR.Close();
81                  dataStream.Close();
82                  response.Close();
83                   return   true ;
84              }
85               else
86              {
87                  BR.Close();
88                  dataStream.Close();
89                  response.Close();
90                  Lat  =   0 ;
91                  Lng  =   0 ;
92                   return   false ;
93              }
94 
95 
96          }

 

最后只要用C#2008 建立一个新项目,添加webbrowser控件,添加一个按键代码如下:

 

 1        Cursor.Current  =  Cursors.WaitCursor;
 2               string  [] cellidFields  =  RIL.GetCellTowerInfo().ToString().Split( ' - ' );
 3                
 4               string [] args  = {
 5                                 cellidFields[ 2 ],
 6                                  " 0 " ,
 7                                 cellidFields[ 1 ],
 8                                 cellidFields[ 0 ]
 9                             };
10               string [] latlng  =  GMM.GetLatLng(args).Split( ' | ' );
11 
12              Uri url  =   new  Uri( " http://maps.google.com/staticmap?&maptype=satellite&key=xxx&markers= "   +  latlng[ 0 ].ToString().Replace( ' , ' ,  ' . ' )  +   " , "   +  latlng[ 1 ].ToString().Replace( ' , ' ,  ' . ' )  +   " &center=,&size=240x320&zoom=18 " );
13              webBrowser1.Navigate(url);
14              Cursor.Current  =  Cursors.Default;

 

 

就只有这些了,如果谁有更好的利用GOOGLE 进行手机基站定位,精度较高的方法,请告诉我,本人不胜感激啊!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值