通过手机所在的基站信息,获取基站所在坐标,从而获知手机当前所在的大概位置。
基站定位无需借助GPS,可供不具备GPS功能的手机使用,也可在GPS信号不良时作为辅助定位手段。
优点:无需借助GPS即可定位,没有额外功耗,定位效果受环境影响小
缺点:只能获得基站所在坐标,精度低,在城郊、野外精度更低
- 查询移动后台,获得坐标信息。优点是可查询所有基站的准确信息;缺点是需要移动鉴权。
- 通过网络向第三方的公开数据库查询。优缺点与前者相反。
本文讨论通过第三方数据库查询。
第三方的基站-坐标数据有以下几个:
- Google我的位置(Google Mobile Maps)
- Open Cell ID
- Yahoo! ZoneTag
由于Google的数据最齐全,因此我们选用Google。
以下协议未找到对应的google官方文档。
需要获取的信息如下:
MCC:国家码,0~999
MNC:运营商码,0~99
LAC:大区号,1~65533、65535
Cell ID:小区号,GSM为4位16进制,UMTS为6位16进制
将要发送给google的数据包长度为55字节,打包方式如下:
BYTE pd[55];
pd[1] = 14; //0x0e;
pd[16] = 27; //0x1b;
pd[47] = 255; //0xff;
pd[48] = 255; //0xff;
pd[49] = 255; //0xff;
pd[50] = 255; //0xff;
pd[28] = (cid > 65536) ? (byte)5 : (byte)3; // GSM uses 4 digits while UTMS used 6 digits (hex)
Shift(pd, 17, mnc);
Shift(pd, 21, mcc);
Shift(pd, 31, cid);
Shift(pd, 35, lac);
Shift(pd, 39, mnc);
Shift(pd, 43, mcc);
//从高位到低位依次放入
void Shift(BYTE* data, int startIndex, int leftOperand) {
int rightOperand = 24;
for (int i = 0; i < 4; i++, rightOperand -= 8) {
data[startIndex++] = (BYTE)((leftOperand >> rightOperand) & 255);
}
}
目标地址:www.google.com/glm/mmap或mobilemaps.clients.google.com/glm/mmap
端口:80
请求类型:POST
http头:"Content-Type: application/binary\r\n"
发送:之前制作的数据包
收到的数据包是25字节(典型)。
int result = GetCode(readBuf, 3);//查询结果,0为成功
double latitude = GetCode(readBuf, 7) / 1e6;//纬度
double longitude = GetCode(readBuf, 11) / 1e6;//精度
int GetCode(BYTE* data, int startIndex)
{
int a = data[startIndex++] << 24;
int b = data[startIndex++] << 16;
int c = data[startIndex++] << 8;
int d = data[startIndex++];
return a|b|c|d;
}
数据中的结果码、经纬度都是按字节顺序存放的。经纬度倒序后作为int读取,除以1e6即为经纬度。
如此,就获得了经纬度坐标。
按google的坐标习惯,西经和南纬应该是用负坐标表示,未证实。
以下为Google Gears中的Geolocation API的网络协议。
需要获取的信息除MCC、MNC、LAC、CID之外,还可提供以下几个(都是可选):
信号强度
TAD(timing_advance)
Wifi网关mac地址
发送的数据包采用json格式,具体格式及参数列表详见文后链接。这里仅列出基站定位所必需的参数。
{
"version": "1.1.0",
"host": "www.stelcom.com.cn",
"cell_towers": [
{
"cell_id": %d,
"location_area_code": %d,
"mobile_country_code": %d,
"mobile_network_code": %d
}
]
}\n
可以包含一或多个小区信息。直接以文本格式打包(char),中间不能换行。
Host:www.google.com
端口:80
请求类型:POST
路径:/loc/json
传输类型:Content-Type: application/json\r\n
返回的数据包也是json格式,如发送前述格式的数据,将以文本格式返回:
{"location":{"latitude":24.530473,"longitude":118.138119,"accuracy":877.0},"access_token":"2:aXxveBUWXkMOHgJv:xVRTz9Ec9wGmIZqW"}
根据标签进行解析即可。可参考文后链接中的json解析代码,也可自行编写简化的解析代码。
可以在发送的包中加入
"request_address": true,
"address_language": "zh_CN",
这样返回的信息就会包含地址信息。中文地址为UTF-8格式,需要在解析后进行转换。返回值形如:
{"location":{"latitude":24.53604,"longitude":118.142704,"address":
{"country":"涓浗","country_code":"CN","region":"绂忓缓鐪?,"
city":"鍘﹂棬甯?,"street":"鏋嬮挓璺?,"
street_number":"1917鍙?},"accuracy":1964.0},
"access_token":"2:ekVQOBs9XgK9jMnl:Xf_FvaO3HosWmiUf"}
http://maps.google.com/maps?f=q&hl=zh-cn&q=24.530473,118.138119&ie=UTF8&t=h&z=15
google maps全球版的卫星照片与坐标对应是准确的。
http://www.google.com/mobile/maps/
http://forum.openhandsetdevelopers.com/google-maps-with-my-location-my-location-t19.html
Learn How to Find GPS Location on Any SmartPhone, and Then Make it Relevant- CodeProject
OpenCelliD - Largest Open Database of Cell Towers & Geolocation - by Unwired Labs
http://zonetag.research.yahoo.com/
Geolocation API Network Protocol
http://code.google.com/intl/zh-CN/apis/gears/geolocation_network_protocol.html
JSON(有参考代码)