zoukankan      html  css  js  c++  java
  • 通过Web页面获取基站位置(Web端,源码下载)转

    from:http://www.cnblogs.com/psunny/archive/2010/04/17/1714427.html

    源代码地址:https://files.cnblogs.com/psunny/SafetyNetMobileHttpService.rar

    我在使用Windows Mobile向http://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

     说明:

    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"
    }

     

     说明:

    即使只发送一个基站信息,也能够获取到一个经纬度。以上的RequestJson和ResponseJson只是样例,在实际Windows Mobile运用中,有可能取不到timing_adavance和singal_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. 生成发往google的json串
    //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 Response的JSON串,获取经纬度
    /// </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#" AutoEventWireup="true"  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>
  • 相关阅读:
    jquery对同级的td做radio限制
    "javascript:void(0)"用法
    SQL 插入查询的最大ID 号 进行批量
    Java数字、货币值和百分数等的格式化处理
    PHP 注意问题
    Android Fragment真正意义上的onResume和onPause
    Android_CodeWiki_03
    Android_CodeWiki_02
    Android_CodeWiki_01
    Android 启动APP黑屏解决方案
  • 原文地址:https://www.cnblogs.com/94cool/p/2512745.html
Copyright © 2011-2022 走看看