AGPS定位基本原理浅析

来源:互联网 发布:网络教育好不好毕业 编辑:程序博客网 时间:2024/05/16 00:38

AGPS定位基本原理浅析

2010-12-12 21:03 by MagicBoy110, 13899阅读, 17评论,收藏,编辑

位置服务已经成为越来越热的一门技术,也将成为以后所有移动设备(智能手机、掌上电脑等)的标配。随着人们对BLS(Based Location Serices,基于位置的服务)需求的飞速增长,无线定位技术也越来越得到重视。AGPSAssisted GPSA-GPS,网络辅助GPS)定位技术结合了GPS定位和蜂窝基站定位的优势,借助蜂窝网络的数据传输功能,可以达到很高的定位精度和很快的定位速度,在移动设备尤其是手机中被越来越广泛的使用。本文以GSM网络辅助GPS定位为例对AGPS的定位原理进行简单介绍。

AGPS定位基本机制

根据定位媒介来分,定位技术基本包含基于GPS的定位和基于蜂窝基站的定位两类(阅读本文前,建议先阅读《GPS定位基本原理浅析》和《GSM蜂窝基站定位基本原理浅析》两篇文章)。GPS定位以其高精度得到更多的关注,但是其弱点也很明显:一是硬件初始化(首次搜索卫星)时间较长,需要几分钟至十几分钟;二是GPS卫星信号穿透力若,容易受到建筑物、树木等的阻挡而影响定位精度。AGPS定位技术通过网络的辅助,成功的解决或缓解了这两个问题。对于辅助网络,有多种可能性,以GSM蜂窝网络为例,一般是通过GPRS网络进行辅助。

说明: AGPS_thumb30

如上图所示,直接通过GPS信号从GPS获取定位所需的信息,这是传统GPS定位的基本机制。AGPS中,通过蜂窝基站的辅助来解决或缓解上文提到的两个问题:

对于第一个问题,首次搜星慢的问题,根据《GPS定位基本原理浅析》一文的介绍,我们知道是因为GPS卫星接收器需要进行全频段搜索以寻找GPS卫星而导致的。在AGPS中,通过从蜂窝网络下载当前地区的可用卫星信息(包含当地区可用的卫星频段、方位、仰角等信息),从而避免了全频段大范围搜索,使首次搜星速度大大提高,时间由原来的几分钟减小到几秒钟。

对于第二个问题,GPS卫星信号易受干扰的问题,这是由GPS卫星信号本身的性质决定的,我们无法改变。但是APGS中,通过蜂窝基站参考GPS的辅助,或是借助GSM定位中Cell-ID定位(COO定位)方法的辅助,缓解了在GPS信号不良的情况下定位的问题,有效提高了在此情况下的定位精度。

AGPS定位基本流程

 

1.搜索卫星

AGPS定位仍然是基于GPS的,因此定位的首要步骤还是先搜索到当前地区的可用GPS卫星。在传统GPS定位中需要全频段搜索以找到可用卫星因而耗时较长,而AGPS通过网络直接下载当前地区的可用卫星信息,从而提高了搜星速度。同时,也减小了设备的电量消耗。

说明: AGPS1_thumb11

如上图所示,AGPS中从定位启动到GPS接收器找到可用卫星的基本流程如下:

1)设备从蜂窝基站获取到当前所在的小区位置(即一次COO定位)

2)设备通过蜂窝网络将当前蜂窝小区位置传送给网络中的AGPS位置服务器

3APGS位置服务器根据当前小区位置查询该区域当前可用的卫星信息(包括卫星的频段、方位、仰角等相关信息),并返回给设备

4GPS接收器根据得到的可用卫星信息,可以快速找到当前可用的GPS卫星

至此,GPS接收器已经可正常接收GPS信号,GPS初始化过程结束。AGPS对定位速度的提高就主要体现在此过程中。

2.计算位置

GPS接收器一旦找到四颗以上的可用卫星,就可以开始接收卫星信号实现定位。接下来的过程根据位置计算所在端的不同,通常有两种方案:在移动设备端进行计算的MS-Based方式和在网络端进行计算的MS-Assisted方式。

MS-Based方式中,接下来过程与传统GPS定位完全相同,GPS接收器接收原始GPS信号,解调并进行一定处理,根据处理后的信息进行位置计算,得到最终的位置坐标。

MS-Assisted方式中,解调并处理后,接下来的过程如下图所示:

5)设备将处理后的GPS信息(伪距信息)通过蜂窝网络传输给AGPS位置服务器

6AGPS服务器根据伪距信息,并结合其他途径(蜂窝基站定位、参考GPS定位等)得到的辅助定位信息,计算出最终的位置坐标,返回给设备。

说明: AGPSMSAssisted_thumb13

在此过程中可以看到,在使用MS-Assisted方式时,由于辅助定位信息的加入,可以取得更高的定位精度;同时,可以很大程度上克服弱GPS信号情况下的无法定位或精度降低的问题;将复杂计算转移到网络端,也可以很大程度上减小设备的电量消耗。

AGPS定位优劣分析

与传统GPS定位相比,APGS定位有如下的优势:

·        首次搜星速度快

·        有效减少设备的电量消耗

对于采用MS-Assisted方式的AGPS系统而言,除了以上优势外,还有:

·        定位精度更高

·        缓解弱GPS信号情况下无法定位或精度降低的问题

·        对移动设备的计算能力要求更低

当然,AGPS也有一定的限制:

·        必须有蜂窝网络(GRRS/EDGE/CDMA等)的支持用以数据传输,对一般用户而言可能需要为此支付一定的数据流量费用

·        必须有AGPS位置服务器的支持

·        GPS一样,仍无法完美解决室内(室内无法接收GPS信号)定位的问题

AGPS定位技术的实际应用情况

因为AGPS需要网络支持,因此目前使用该技术的大部分设备为手机。

1.目前大部分支持AGPS的手机采用一种纯软件的AGPS方案。


该方案基于MS-Based位置计算方式。具体的方案为:

定期下载星历数据到手机中,手机中的AGPS软件会根据星历信息计算出当前位置的可用卫星信息,从而提供给设备用于快速搜星。用户可以选择通过WiFi、固网等免费网络定期更新星历数据,从而避免使用蜂窝网络产生的数据流量费用。当然,由于星历信息可能存在延迟,因此搜星时速度可能有所下降,但是仍然会比传统GPS定位快很多倍。

该方案的优点是纯软件,不需要专门的AGPS硬件,几乎所有GPS手机都可以使用;同时用户可以根据情况指定星历更新周期及更新方式,控制或减免蜂窝网络数据流量。

HTC的大部分AGPS手机都采用这种方案。如下图为HTC手机中用于更新卫星信息的快速GPS”软件。
说明: HTCGPS1_thumb1说明: HTCGPS2_thumb1

 

2.部分运营商的AGPS方案中,实施了在无GPS信号时自动切换到GSM蜂窝基站Cell-ID定位的措施,从而一定程度上解决了室内定位的问题。

如中国移动的OMA AGPS方案。

说明: OMAAGPS_thumb2

 

3.世界范围内一些AGPS芯片或相关服务已经广泛使用。

SiRF公司的AGPS芯片提供了硬件层次上的AGPS方案。

说明: SiRFAGPSChip_thumb

U-BloxAssistNow A-GPS服务提供了AssistNow Online(在线AssistNow)AssistNow OffLine(离线AssistNow)两种易用的AGPS方案。实际上这两种方案分别就是MS-AssistedMS-Based两种定位计算方式的实现。

u-blox在线AssistNow系统组成。

说明: ubloxAssistNow_thumb9

u-blox离线AssistNow系统组成。

说明: ubloxAssistNow_thumb1

4.国内电信运营商的AGPS方案

中国移动正在制订的A-GPS方案基于OMASUPL规范,是一种用户平面的解决方案。

中国联通提供的gpsOneMS-Assisted方式的A-GPS定位方案,也基于用户平面方式,目前只用于CDMA网络。

要了解二者的详细信息,请自行Google。下面仅列出几个可能有用的链接。

·        中国移动AGPS技术引入策略

·        中国移动终端A-GPS技术规范3.0

·        2008-2009年中国移动位置服务(LBS)研究咨询报告

·        浅析 CDMA 移动通信网络下定位功能的实现

 

GPS定位GSM蜂窝基站定位AGPS定位是目前最流行的三种定位方式。AGPS定位基于GPS,却又借助蜂窝网络避免了GPS定位的两大软肋,无疑是最具竞争力的一种定位方案。随着3G时代的到来,BLS业务已成为各大运营商的必争之地,这其中,AGPS方案绝对是竞争中很重要的一部分。希望本文能让你对AGPS技术有一个大致的了解。


 

通过Web页面获取谷歌基站位置

说明: http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif(2010-11-09 18:30:43)

说明: http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif转载▼

标签:

it

分类: tech

在使用Windows Mobilehttp://www.google.com/loc/json请求基站信息时,发现第一次发送基站信息能够获取到一个经纬度,第二次却失败,直接导致异常退出应用程序。由于基站信息只能在真机上才能获取,无法进行调试,我就以一个中间web页面来向手机发送位置信息,再者拼接Json和解析的Json都放在web上进行处理,也减少Windows Mobile应用程序的负担,Windows Mobile只单纯的负责接收一个经纬度字符串。

1. 具体思路

 首先要清楚一点的是,每一个基站都能够通过请求http://www.google.com/loc/json获取到一个经纬度。如果用户能够在短时间内获取到较多的基站信息,比如4个或5个,可以通过这几个基站的经纬度计算出比较准确的用户位置。

举个例子,比如我在WM上取到4个基站信息:

50554,9513,460,1

50325,9513,460,1

50584,9513,460,1

50041,9513,460,1

每一行的4个数值分别对应:CID, LAC, MCC, MNC

说明: http://i.msdn.microsoft.com/Bb397906.alert_note(zh-cn,VS.90).gif说明:

CID——CellID,表示基站号
LAC
——Location Area Code,表示区域编号

MCC——Mobile Country Code,表示国家编号,中国是460

MNC——Mobile Network Code,表示移动网络编号,移动是0,联通是1

更详细的MCC, MNC信息可以查看:http://en.wikipedia.org/wiki/Mobile_Network_Code

然后向Google发送基站信息是通过JSON串以Post的形式发送到http://www.google.com/loc/json,然后它会返回一个包含经纬度信息的JSON串。

RequestJson范例

{
  "version": "1.1.0",
  "host": "maps.google.com",
  "cell_towers": [
    {
      "cell_id": 42,
      "location_area_code": 415,
      "mobile_country_code": 310,
      "mobile_network_code": 410,
      "age": 0,
      "signal_strength": -60,
      "timing_advance": 5555
    },
    {
      "cell_id": 88,
      "location_area_code": 415,
      "mobile_country_code": 310,
      "mobile_network_code": 580,
      "age": 0,
      "signal_strength": -70,
      "timing_advance": 7777
    }
  ],
  "wifi_towers": [
    {
      "mac_address": "01-23-45-67-89-ab",
      "signal_strength": 8,
      "age": 0
    },
    {
      "mac_address": "01-23-45-67-89-ac",
      "signal_strength": 4,
      "age": 0
    }
  ]
}

然后从google那边返回来的位置信息如下:

ResponseJson样 例

{
  "location": {
    "latitude": 51.0,
    "longitude": -0.1,
    "altitude": 30.1,
    "accuracy": 1200.4,
    "altitude_accuracy": 10.6,
    "address": {
      "street_number": "100",
      "street": "Amphibian Walkway",
      "postal_code": "94043",
      "city": "Mountain View",
      "county": "Mountain View County",
      "region": "California",
      "country": "United States of America",
      "country_code": "US"
    }
  },
  "access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
}

 

说明: http://i.msdn.microsoft.com/Bb397906.alert_note(zh-cn,VS.90).gif说明:

即使只发送一个基站信息,也能够获取到一个经纬度。以上的 RequestJsonResponseJson只是样例,在实际Windows Mobile运用中,有可能取不到timing_adavancesingal_strength这两个参数,结合这两个参数定位会更准确一些。在我的代码例子中,我只取了CID, LAC, MCC, MNC参数。

关于JSON串中的属性各代表什么意思,详细请看:http://code.google.com/intl/zh-CN/apis/gears/geolocation_network_protocol.html

 

从上面的两端代码中我们可以大致了解到如何向Google发送基站请求,获取经纬度,下面我就以简单的代码来实现获取经纬度的方法。其实了解了上面的代码后,我们主要的工作就是拼接RequestJson串和解析
ResponseJson
串,解析Json串我使用的是JSON.NET

2.实现

 

 

基站 类:CellInfo.cs

using System;

/// <summary>
/// CellInfocs
的摘要说明
/// </summary>
public class CellInfo
{
    public string cid;
    public string lac;
    public string mcc;
    public string mnc;

    public string CID
    {
        get { return cid; }
        set { cid = value; }
    }

    public string LAC
    {
        get { return lac; }
        set { lac = value; }
    }

    public string MCC
    {
        get { return mcc; }
        set { mcc = value; }
    }

    public string MNC
    {
        get { return mnc; }
        set { mnc = value; }
    }

}

 

主要的 类:LocationService.cs 

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using Newtonsoft.Json.Linq;

/// <summary>
/// LocationService
的摘要说明
/// </summary>
public class LocationService
{
    public static string ErrorMessage;

    public LocationService(string postData)
    {
        GetLocationInfomation(postData);
    }

    /// <summary>
    ///
返回经纬度信息
    ///
格式如下:
    /// 22.506421,113.918245|22.497636,113.912647|22.496063,113.91121
    /// </summary>
    /// <param name="postData"></param>
    /// <returns></returns>
    public string GetLocationInfomation(string postData)
    {
        List<CellInfo> list = GetCellInfos(postData);
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < list.Count; i++)
        {
            CellInfo info = list[i];
            //
基本步骤
            //1.
生成发往googlejson
            //2.
接收google返回的json
            //3.
解析json串,只取得经纬度
            //4.
拼接经纬度
            string json = GenerateRequestJson(info);
            string content = GetResponseJson(json);
            string latLon = ParseResponseJson(content);

            sb.Append(latLon);
            sb.Append("|");
        }

        return sb.ToString().Substring(0, sb.Length - 1);
        //return sb.ToString();
    }

    /// <summary>
    ///
接收从手机端发送过来的数据
    /// '|'
分割对象,','分割属性
    /// </summary>
    /// <param name="postData"></param>
    /// <returns></returns>
    private List<CellInfo> GetCellInfos(string postData)
    {
        string[] strInfos = postData.Split('|');
        List<CellInfo> list = new List<CellInfo>();
        for (int i = 0; i < strInfos.Length; i++)
        {
            string[] properties = strInfos[i].Split(',');
            CellInfo info = new CellInfo();

            info.CID = properties[0];
            info.LAC = properties[1];
            info.MCC = properties[2];
            info.MNC = properties[3];

            list.Add(info);
        }
        return list;
    }


    /// <summary>
    ///
发送一个基站信息,并返回一个位置信息
    ///
位置信息是以json串的形式存在
    ///
需要对json串进行解析
    /// </summary>
    /// <param name="requestJson"></param>
    private string GetResponseJson(string requestJson)
    {
        string responseJson = string.Empty;
        try
        {
            ServicePointManager.Expect100Continue = false;
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] data = encoding.GetBytes(requestJson);

            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(@"http://www.google.com/loc/json");


            myRequest.Method = "POST";
            myRequest.ContentType = "application/requestJson";
            myRequest.ContentLength = data.Length;
            Stream newStream = myRequest.GetRequestStream();

            // Send the data.
            newStream.Write(data, 0, data.Length);
            newStream.Close();

            // Get response JSON string
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

            StreamReader reader = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.Default);
            responseJson = reader.ReadToEnd();
        }
        catch (Exception ex)
        {
            ErrorMessage = ex.Message;
        }

        return responseJson;
    }

    /// <summary>
    ///
解析从google ResponseJSON串,获取经纬度
    /// </summary>
    /// <param name="responseJson"></param>
    /// <returns></returns>
    private string ParseResponseJson(string responseJson)
    {
        StringBuilder latLon = new StringBuilder();
        JObject obj = JObject.Parse(responseJson);

        string lat = obj["location"]["latitude"].ToString();
        string lon = obj["location"]["longitude"].ToString();

        latLon.Append(lat);
        latLon.Append(",");
        latLon.Append(lon);

        return latLon.ToString();
    }

    /// <summary>
    ///
生成发往http://www.google.com/loc/json的json
    ///
仅仅只有一个基站
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    private string GenerateRequestJson(CellInfo info)
    {

        string json = "";
        json += "{";
        json += "\"version\":\"1.1.0\"" + ",";
        json += "\"host\":\"maps.google.com\"" + ",";
        json += "\"cell_towers\":[";

        json += "{";
        json += "\"cell_id\":" + info.CID + ",";
        json += "\"location_area_code\":" + info.LAC + ",";
        json += "\"mobile_country_code\":" + info.MCC + ",";
        json += "\"mobile_network_code\":" + info.MNC;
        json += "}";

        json += "],";
        json += "\"wifi_towers\": [{}]";
        json += "}";

        return json;
    }
}

 

中间的web页面:Default.aspx(发送请求时,就请求这个页面)

<%@ Page Language="C#"   CodeFile="Default.aspx.cs" Inherits="_Default" %>

 

using System;

public partial class _Default : System.Web.UI.Page
{

    protected void Page_Load(object sender, EventArgs e)
    {
        string postData = Request.Form["POST_DATA"];
        ResponseLocation(postData);
    }


    /// <summary>
    ///
向手机端返回位置信息
    /// </summary>
    /// <param name="postData"></param>
    public void ResponseLocation(string postData)
    {
        LocationService service = new LocationService(postData);
        string location = service.GetLocationInfomation(postData);
        Response.Write(location);
    }
}

 

测试页面:index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Index Page</title>
</head>
<body>
<form id="form1" method="post" action="Default.aspx">
    <input name="POST_DATA"
        value=" 50554,9513,460,1|50325,9513,460,1|50584,9513,460,1|50041,9513,460,1"/>
    <input type="submit"/>
</form>
</body>
</html>

 

 

  

 

说明: C:\Program Files\Common Files\Microsoft Shared\Stationery\CIMC-30.png

   

 

 

 GSM蜂窝基站定位基本原理浅析

2010-12-10 23:49 by MagicBoy110, 8324阅读, 9评论,收藏,编辑

位置服务已经成为越来越热的一门技术,也将成为以后所有移动设备(智能手机、掌上电脑等)的标配。随着人们对BLS(Based Location Serices,基于位置的服务)需求的飞速增长,无线定位技术也越来越得到重视。GSM蜂窝基站定位,以其定位速度快、成本低(不需要移动终端上添加额外的硬件)、耗电少、室内可用等优势,作为一种轻量级的定位方法,也越来越常用。本文简单介绍一下各种基于GSM蜂窝基站的定位方法及基本原理,给开发人员作为参考。我将尽量尝试用开发人员熟悉的方式来描述问题。

预备知识:GSM蜂窝网络基础结构

我们知道,GSM网络的基础结构是由一系列的蜂窝基站构成的,这些蜂窝基站把整个通信区域划分成如图所示的一个个蜂窝小区(当然实际上,一个基站往往不并不只是对应一个小区,但是这个与我们讨论的主题关系不大,我们不做深究)。这些小区小则几十米,大则几千米。如下图所示,我们用移动设备在GSM网络中通信,实际上就是通过某一个蜂窝基站接入GSM网络,然后通过GSM网络进行数据(语音数据、文本数据、多媒体数据等)传输的。也就是说我们在GSM中通信时,总是需要和某一个蜂窝基站连接的,或者说是处于某一个蜂窝小区中的。那么GSM定位,就是借助这些蜂窝基站进行定位。

说明: 2009698297_thumb1

 

1.COOCell of Origin)定位

COO定位是一种单基站定位,即根据设备当前连接的蜂窝基站的位置来确定设备的位置。那么很显然,定位的精度就取决于蜂窝小区的半径。在基站密集的城市中心地区,通常会采用多层小区,小区划分的很小,这时定位精度可以达到50M以内;而在其他地区,可能基站分布相对分散,小区半径较大,可能达到几千米,也就意味着定位精度只能粗略到几千米。目前Google地图移动版中,通过蜂窝基站确定我的位置,基本上用的就是这种方法。

从原理上我们可以看出,COO定位其精度是不太确定的。但是这却是GSM网络中的移动设备最快捷、最方便的定位方法,因为GSM网络端以及设备端都不需要任何的额外硬件投入。只要运营商支持,GSM网络中的设备都可以以编程方式获取到当前基站的一个唯一代码,我们可以称之为基站ID,或CellID。在一般的设备中,可能都存在一个类似如下的GetCurrentCellID()方法的接口来提供当前GSM蜂窝基站ID

CellID = GetCurrentCellID();

通过这个接口获取到CellID后,我们还需要根据这个CellID查出该蜂窝基站所在的具体地理坐标。这时,我们可能就需要调用一些包含[CellID,地理坐标]对应关系的外部数据以确定相应的地理坐标。这个外部数据,通常可以由一些第三方Web服务来提供。这些Web服务的接口可能类似于如下形式:

Position=GetPosition(CellID);

当然,再次说明,上面的GetCurrentCellID方法、GetPosition方法都是我虚构的,只是为了说明逻辑关系,并不一定实际存在。关于COO方法在Windows Mobile环境下的具体编程方法,请参考《Windows Mobile设备创建位置感知的应用程序》。

 

2.七号信令定位

该技术以信令监测为基础,能够对移动通信网中特定的信令过程,如漫游、切换以及与电路相关的信令过程进行过滤和分析,并将监测结果提供给业务中心,以实现对特定用户的个性化服务。该项技术通过对信令进行实时监测,可定位到一个小区,也可定位到地区。故适用对定位精确度要求不高的业务,如漫游用户问候服务,远程设计服务、平安报信和货物跟踪等。目前,国内各省和地区移动公司的短信欢迎系统采用的就是此种技术。

 

7.TOA/TDOA定位

TOA(Time of Arrival,到达时间)TDOA(Time Difference of Arrival,到达时间差)都是基于电波传播时间的定位方法。同时也都是三基站定位方法,二者的定位都需要同时有三个位置已知的基站合作才能进行。

说明: TOA_DTOA_thumb6

如上图所示,TOA/DTOA定位方法都是通过三对[Positioni,Ti]i=1,2,3)来确定设备的位置Location。二者的不同只是GetLocation()函数的具体算法上的不同。

TOA电波到达时间定位基本原理是得到Ti(i=1,2,3)后,由Ti*c得到设备到基站i之间的距离Ri,然后根据几何只是建立方程组并求解,从而求得Location值。如下图所示。

说明: TOA_thumb1

由于图中距离的计算完全依赖于时间,因此TOA算法对系统的时间同步要求很高,任何很小的时间误差都会被放大很多倍,同时由于多径效应的影响又会带来很大的误差,因而单纯的TOA在实际中应用很少。

DTOA电波到达时间差定位是对TOA定位的改进,与TOA的不同之处在于,得到Ti后不是立即用Ti去求距离Ri,而是先对T1,T2,T3两两求差,然后通过一些巧妙的数学算法建立方程组并求解,从而得到Location值。如下图所示。

说明: DTOA_thumb

DTOA由于其中巧妙设计的求差过程会抵消其中很大一部分的时间误差和多径效应带来的误差,因而可以大大提高定位的精确度。

由于DTOA对网络要求相对较低,并且精度较高,因而目前已经成为研究的热点。

 

4.AOA定位

AOA(Angle of Arrival,到达角度)定位是一种两基站定位方法,基于信号的入射角度进行定位。

说明: AOA_thumb

如上图所示,知道了基站1到设备之间连线与基准方向的夹角α1,就可以画出一条射线L1;同样知道了知道了基站2到设备之间连线与基准方向的夹角α2,就可以画出一条射线L2。那么L1L2的交点就是设备的位置。这就是AOA定位的基本数学原理。用函数调用表达如下。

Location=GetLocation([Pisition1,α1],[Position2,α2]);

AOA定位通过两直线相交确定位置,不可能有多个交点,避免了定位的模糊性。但是为了测量电磁波的入射角度,接收机必须配备方向性强的天线阵列。

5.基于场强的定位

该方法是通过测出接收到的信号场强和已知的信道衰落模型及发射信号的场强值估计收发信短的距离,根据多个三个距离值就可以得到设备的位置。从数学模型上看,和TOA算法类似,只是获取距离的方式不同。场强算法虽然简单,但是由于多径效应的影响,定位精度较差。

6.混合定位

混合定位就是同时使用两种以上的定位方法来进行定位。通过各种定位方法之间结合使用,互补短长,以达到更高的定位精度。

A-GPS定位(辅助GPS定位)就是一种混合定位,是GPS定位技术与GSM网络的结合。A-GPS具有很高的定位精度,目前正被越来越广泛的使用。

 

GPS定位作为一种传统的定位方法,仍是目前应用最广泛、定位精度最高的定位技术。但是相对而言,GPS定位成本高(需要终端配备GPS硬件)、定位慢(GPS硬件初始化通常需要3~5分钟甚至10分钟以上的时间)、耗电多(需要额外硬件自然耗电多),因此在一些定位精度要求不高,但是定位速度要求较高的场景下,并不是特别适合;同时因为GPS卫星信号穿透能力弱,因此在室内无法使用(关于GPS的定位原理可参考GPS定位基本原理浅析)。相比之下,GSM蜂窝基站定位快速、省电、低成本、应用范围限制小,因此在一些精度要求不高的轻型场景下,也大有用武之地。关于在Windows Mobile环境下GPS定位和GSM蜂窝基站定位的相关开发技术,可参考Windows Mobile备创建位置感知的应用程序


 

 

 Wince

发表于:2011-03-07 10:41:06

先自我介绍一下啊,嘿嘿,我是刚开始做wince开发的,绝对菜鸟
 
今天老大让我弄基站定位,在那个ril.dll获取的时候报错了
 
在网上查了资料也不会弄,说6.0ril.dll5.0的不兼容 CSDN下载了几个试了都不用不了
  =
=插入不了图片,我吧我代码贴出来吧···
 
希望各位高手能教教我,嘿嘿
#region
获取基站定位
CellInfo cell=Ril.GetCellTowerInfo();
这里报错,提示无法找到Pinvoke DLL "ril.dll"
  string code=string.Format("CID:{0} MCC:{1} LAC:{2} MNC:{3}",cell.CID,cell.MCC,cell.LAC,cell.MNC);
#endregion 

我在网上下载了几个ril.dll放进去还是不行···
  CSDN
上面有个说是5.0DLL但是下载了不知道弄,那里面没有直接的Dll文件,要我做什么什么处理,嘿嘿,新手,不懂
 
望各位老大能教教小弟我,万分感谢····

 

 android GSM+CDMA基站定位

 

googleAPI里提供了基站信息的获取类TelephonyManager,通过其方法getCellLocation得到CellLocation即可获取到基站相关信息

CellLocation是个抽象类,所以在具体使用时需要判断接入的网络制式来用其子类CdmaCellLocationGsmCellLocation来强转

CdmaCellLocation对应CDMA网,GsmCellLocation对应GSM

三大网络运营商的网络制式对应如下:

移动2G --> GSM

移动3G --> TD-SCDMA

电信2G --> CDMA

电信3G --> CDMA2000

联通2G --> GSM

联通3G --> WCDMA

由此可见移动,联通2G 网都可使用GsmCellLocation

电信2G,3G网则使用CdmaCellLocation

那么移动3G和联通3G又当如何

其实经本人亲测,移动3G网也可使用GsmCellLocation,听说是TD-SCDMA衍生于GSM,具体原因咱也不用纠结了,反正能用就是了

而联通的WCDMA据说也可使用GsmCellLocation,那姑且就是这样吧,有条件的童鞋试一试吧。

对于网络制式的判断调用TelephonyManager.getNetworkType()可有多种情况,如下:

  • NETWORK_TYPE_UNKNOWN
  • NETWORK_TYPE_GPRS
  • NETWORK_TYPE_EDGE
  • NETWORK_TYPE_UMTS
  • NETWORK_TYPE_HSDPA
  • NETWORK_TYPE_HSUPA
  • NETWORK_TYPE_HSPA
  • NETWORK_TYPE_CDMA
  • NETWORK_TYPE_EVDO_0
  • NETWORK_TYPE_EVDO_A
  • NETWORK_TYPE_EVDO_B
  • NETWORK_TYPE_1xRTT
  • NETWORK_TYPE_IDEN
  • NETWORK_TYPE_LTE
  • NETWORK_TYPE_EHRPD

通过对网络类型判断后获取对应基站信息代码片段如下:

Html代码 说明: 复制代码

  1. public static ArrayList<CellIDInfo> getCellIDInfo(Context context) throws Exception{   
  2.            
  3.         TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);   
  4.            
  5.         ArrayList<CellIDInfo> CellID = new ArrayList<CellIDInfo>();   
  6.         CellIDInfo currentCell = new CellIDInfo();   
  7.   
  8.         int type = manager.getNetworkType();   
  9.         Log.d(TAG, "getCellIDInfo-->         NetworkType = " + type);   
  10.         int phoneType = manager.getPhoneType();   
  11.         Log.d(TAG, "getCellIDInfo-->         phoneType = " + phoneType);   
  12.            
  13.         if (type == TelephonyManager.NETWORK_TYPE_GPRS              // GSM   
  14.                 || type == TelephonyManager.NETWORK_TYPE_EDGE   
  15.                 || type == TelephonyManager.NETWORK_TYPE_HSDPA)   
  16.         {   
  17.             GsmCellLocation gsm = ((GsmCellLocation) manager.getCellLocation());   
  18.             if (gsm == null)   
  19.             {   
  20.                 Log.e(TAG, "GsmCellLocation is null!!!");   
  21.                 return null;   
  22.             }   
  23.                    
  24.   
  25.             int lac = gsm.getLac();   
  26.             String mcc = manager.getNetworkOperator().substring(0, 3);   
  27.             String mnc = manager.getNetworkOperator().substring(3, 5);   
  28.             int cid = gsm.getCid();   
  29.                
  30.             currentCell.cellId = gsm.getCid();   
  31.             currentCell.mobileCountryCode = mcc;   
  32.             currentCell.mobileNetworkCode = mnc;   
  33.             currentCell.locationAreaCode = lac;   
  34.                
  35.             currentCell.radioType = "gsm";   
  36.                
  37.             CellID.add(currentCell);   
  38.                
  39.             // 获得邻近基站信息   
  40.             List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();   
  41.             int size = list.size();   
  42.             for (int i = 0; i < size; i++) {   
  43.   
  44.                 CellIDInfo info = new CellIDInfo();   
  45.                 info.cellId = list.get(i).getCid();   
  46.                 info.mobileCountryCode = mcc;   
  47.                 info.mobileNetworkCode = mnc;   
  48.                 info.locationAreaCode = lac;   
  49.                
  50.                 CellID.add(info);   
  51.             }   
  52.                
  53.         }else if (type == TelephonyManager.NETWORK_TYPE_CDMA        // 电信cdma   
  54.                 || type == TelephonyManager.NETWORK_TYPE_1xRTT   
  55.                 || type == TelephonyManager.NETWORK_TYPE_EVDO_0   
  56.                 || type == TelephonyManager.NETWORK_TYPE_EVDO_A)   
  57.         {   
  58.                
  59.             CdmaCellLocation cdma = (CdmaCellLocation) manager.getCellLocation();      
  60.             if (cdma == null)   
  61.             {   
  62.                 Log.e(TAG, "CdmaCellLocation is null!!!");   
  63.                 return null;   
  64.             }   
  65.                
  66.             int lac = cdma.getNetworkId();   
  67.             String mcc = manager.getNetworkOperator().substring(0, 3);   
  68.             String mnc = String.valueOf(cdma.getSystemId());   
  69.             int cid = cdma.getBaseStationId();   
  70.                
  71.             currentCell.cellId = cid;   
  72.             currentCell.mobileCountryCode = mcc;   
  73.             currentCell.mobileNetworkCode = mnc;   
  74.             currentCell.locationAreaCode = lac;   
  75.        
  76.             currentCell.radioType = "cdma";   
  77.                
  78.             CellID.add(currentCell);   
  79.                
  80.             // 获得邻近基站信息   
  81.             List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();   
  82.             int size = list.size();   
  83.             for (int i = 0; i < size; i++) {   
  84.   
  85.                 CellIDInfo info = new CellIDInfo();   
  86.                 info.cellId = list.get(i).getCid();   
  87.                 info.mobileCountryCode = mcc;   
  88.                 info.mobileNetworkCode = mnc;   
  89.                 info.locationAreaCode = lac;   
  90.                
  91.                 CellID.add(info);   
  92.             }   
  93.         }   
  94.            
  95.         return CellID;   
  96.                
  97.     }  

 


GOOGLEAPI文档里总共有14钟网络类型,这里只罗列了其中7种,其他的主要是本人也不太清楚其对应到的网络制式是怎样的

所以部分童鞋的SIM卡网络制式不在这7种之内,自己根据实际情况看看它是归类于GSM还是CDMA在添进去就可以了


网络上多数教程是讲GSM网获取基站的,而忽略了C网的基站
这里我们可以比较一下GSM CDMA 在获取基站信息时的不同之处



GSM:

int lac = gsm.getLac();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = manager.getNetworkOperator().substring(3, 5);
int cid = gsm.getCid();



CDMA:

int lac = cdma.getNetworkId();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = String.valueOf(cdma.getSystemId());
int cid = cdma.getBaseStationId();



在获取区域码LACGSM使用的是GsmCellLocation.getLac(),CDMA则用CdmaCellLocation.getNetworkId()来代替

在获取基站IDGSM使用的是GsmCellLocation.getCid(),CDMA则用CdmaCellLocation.getBaseStationId()来代替





前面获取到的都是单个基站的信息,后面再获取周围邻近基站信息以辅助通过基站定位的精准性

TelephonyManager.getNeighboringCellInfo()
,将其也放入基站信息LIST表中





最后通过google提供的gear接口获取经纬度,代码如下:

Html代码 说明: 复制代码

  1. public static Location callGear(List<CellIDInfo> cellID) {   
  2.             if (cellID == null || cellID.size() == 0)    
  3.                     return null;   
  4.                
  5.             DefaultHttpClient client = new DefaultHttpClient();   
  6.                 HttpPost post = new HttpPost("http://www.google.com/loc/json");   
  7.                 JSONObject holder = new JSONObject();   
  8.   
  9.                 try {   
  10.                         holder.put("version", "1.1.0");   
  11.                         holder.put("host", "maps.google.com");   
  12.                         holder.put("home_mobile_country_code", cellID.get(0).mobileCountryCode);   
  13.                         holder.put("home_mobile_network_code", cellID.get(0).mobileNetworkCode);   
  14.                         holder.put("radio_type", cellID.get(0).radioType);   
  15.                         holder.put("request_address", true);   
  16.                         if ("460".equals(cellID.get(0).mobileCountryCode))    
  17.                                 holder.put("address_language", "zh_CN");   
  18.                         else   
  19.                                 holder.put("address_language", "en_US");   
  20.                            
  21.                         JSONObject data,current_data;   
  22.   
  23.                         JSONArray array = new JSONArray();   
  24.                            
  25.                         current_data = new JSONObject();   
  26.                         current_data.put("cell_id", cellID.get(0).cellId);   
  27.                         current_data.put("location_area_code", cellID.get(0).locationAreaCode);   
  28.                         current_data.put("mobile_country_code", cellID.get(0).mobileCountryCode);   
  29.                         current_data.put("mobile_network_code", cellID.get(0).mobileNetworkCode);   
  30.                         current_data.put("age", 0);   
  31.                         current_data.put("signal_strength", -60);   
  32.                         current_data.put("timing_advance", 5555);   
  33.                         array.put(current_data);   
  34.                            
  35.                         if (cellID.size() > 2) {   
  36.                             for (int i = 1; i < cellID.size(); i++) {   
  37.                              data = new JSONObject();   
  38.                              data.put("cell_id", cellID.get(i).cellId);   
  39.                              data.put("location_area_code", cellID.get(i).locationAreaCode);   
  40.                              data.put("mobile_country_code", cellID.get(i).mobileCountryCode);   
  41.                              data.put("mobile_network_code", cellID.get(i).mobileNetworkCode);   
  42.                              data.put("age", 0);   
  43.                              array.put(data);   
  44.                             }   
  45.                            }   
  46.   
  47.                            
  48.                            
  49.                            
  50.                         holder.put("cell_towers", array);   
  51.                                                    
  52.                         StringEntity se = new StringEntity(holder.toString());   
  53.                         Log.e("Location send", holder.toString());   
  54.                         post.setEntity(se);   
  55.                         HttpResponse resp = client.execute(post);   
  56.   
  57.                         HttpEntity entity = resp.getEntity();   
  58.   
  59.                         BufferedReader br = new BufferedReader(   
  60.                                         new InputStreamReader(entity.getContent()));   
  61.                         StringBuffer sb = new StringBuffer();   
  62.                         String result = br.readLine();   
  63.                         while (result != null) {   
  64.                                 Log.e("Locaiton reseive-->", result);   
  65.                                 sb.append(result);   
  66.                                 result = br.readLine();   
  67.                         }   
  68.                            
  69.                         data = new JSONObject(sb.toString());   
  70.                          
  71.                         data = (JSONObject) data.get("location");   
  72.   
  73.                         Location loc = new Location(LocationManager.NETWORK_PROVIDER);   
  74.                         loc.setLatitude((Double) data.get("latitude"));   
  75.                         loc.setLongitude((Double) data.get("longitude"));   
  76.                         loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));   
  77.                         loc.setTime( System.currentTimeMillis());//AppUtil.getUTCTime());   
  78.                         return loc;   
  79.                 } catch (JSONException e) {   
  80.                         e.printStackTrace();   
  81.                         return null;   
  82.                 } catch (UnsupportedEncodingException e) {   
  83.                         e.printStackTrace();   
  84.                 } catch (ClientProtocolException e) {   
  85.                         e.printStackTrace();   
  86.                 } catch (IOException e) {   
  87.                         e.printStackTrace();   
  88.                 }   
  89.   
  90.                 return null;   
  91.         }  

 


大家注意看这行holder.put("radio_type", cellID.get(0).radioType);

GSM就用"gsm",CDMA就用"cdma"

这个千万别搞混了,不然就获取不到信息了

值得一提的是C网获取基站再定位那偏差不是一般的大,是恨大,将近1千米了,大概是C网基站较少的缘故吧

最后通过经纬度获取地理位置信息,代码如下:

Java代码 说明: 复制代码

  1. public static  String getAddress(Location itude) throws Exception {   
  2.         String resultString = "";   
  3.     
  4.         /** 这里采用get方法,直接将参数加到URL */  
  5.         String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.getLatitude(), itude.getLongitude());   
  6.         Log.i("URL", urlString);   
  7.     
  8.         /** 新建HttpClient */  
  9.         HttpClient client = new DefaultHttpClient();   
  10.         /** 采用GET方法 */  
  11.         HttpGet get = new HttpGet(urlString);   
  12.         try {   
  13.             /** 发起GET请求并获得返回数据 */  
  14.             HttpResponse response = client.execute(get);   
  15.             HttpEntity entity = response.getEntity();   
  16.             BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));   
  17.             StringBuffer strBuff = new StringBuffer();   
  18.             String result = null;   
  19.             while ((result = buffReader.readLine()) != null) {   
  20.                 strBuff.append(result);   
  21.             }   
  22.             resultString = strBuff.toString();   
  23.     
  24.             Log.e("resultAdress--->", resultString);   
  25.                
  26.             /** 解析JSON数据,获得物理地址 */  
  27.             if (resultString != null && resultString.length() > 0) {   
  28.                 JSONObject jsonobject = new JSONObject(resultString);   
  29.                 JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());   
  30.                 resultString = "";   
  31.                 for (int i = 0; i < jsonArray.length(); i++) {   
  32.                     resultString = jsonArray.getJSONObject(i).getString("address");   
  33.                 }   
  34.             }   
  35.         } catch (Exception e) {   
  36.             throw new Exception("获取物理位置出现错误:" + e.getMessage());   
  37.         } finally {   
  38.             get.abort();   
  39.             client = null;   
  40.         }   
  41.     
  42.         return resultString;   
  43.     }  

 

在获取地理位置的这个location事实上应该传入纠偏后的location,本文暂不做此处理,所以得到的地理信息位置是偶偏差的,大家注意

最后附上截图:

说明: http://img.my.csdn.net/uploads/201205/30/1338369996_6566.JPG

工程下载链接:http://download.csdn.net/detail/geniuseoe2012/4340303

原创粉丝点击