Android中的三角测量收到了错误的位置

时间:2012-08-15 20:41:18

标签: android geolocation triangulation

这有点宽泛,但我们走了:我的三角测量算法出现了一个非常奇怪的问题。有时,它返回正确的纬度/经度,然后,经过一段时间后,它会返回错误的纬度/经度。更奇怪的是,我无法预测这个错误何时会发生,也不能再现它。即使我不更改代码中的行(接收正确的值,然后错误,然后更正等等),也会发生这种情况。

我正在使用Google GLM服务,将设备LAC(位置区域代码)和Tower ID发送到我的位置三角形。我的算法的核心方法如下:

private double[] getPositionByTriangle(int lac, int cid) {
    int shortcid = cid & 0xffff;
    double location[] = new double[2];
    try {
        String surl = "http://www.google.com/glm/mmap";
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(surl);
        httppost.setEntity(new CellIDRequestEntity(shortcid, lac));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        DataInputStream dis = new DataInputStream(entity.getContent());
        // Read some prior data
        dis.readShort();
        dis.readByte();
        // Read the error-code
        int errorCode = dis.readInt();
        if (errorCode == 0) {
            location[0] = (double) dis.readInt() / 1000000D;
            location[1] = (double) dis.readInt() / 1000000D;
        }
    } catch (Exception e) {}
    return location;
}

额外的信息,可能会有所帮助:此方法用于扩展Android服务的类,通过PendingIntent延迟1分钟调用。调用它的线程会在SharedPreferences中保存lat / lon值,然后在所有视图中使用它。

我想知道我是否用错误的算法实现了这个方法,或者我是否错过了过程中的技巧。目前,我正确的近似lat / lon值为纬度= -23 经度= -46 ,但我接收(有时)纬度=的值17 经度= 81 。有人能给我一些关于发生了什么的暗示吗?

1 个答案:

答案 0 :(得分:0)

好的。我自己找到了解决方案。开始了。 三角测量过程基本上是一个三参数组合过程。基于我已经完成的一些搜索,我推断出您可以使用不同类型的数据组合。我使用的组合是塔架ID(设备握手的塔式收发器),位置代码(区号和国家代码)以及位置区域代码的混合。所以,我的新代码如下所示:

TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation.requestLocationUpdate();
location = (GsmCellLocation) tm.getCellLocation();
networkOperator = tm.getNetworkOperator();
cellID = location.getCid();
lac = location.getLac();

public double[] getLocationByMCCMNC(String mcc, String mnc, String lac, String cellId, boolean requestAddress) throws IOException {

    final String data = "{\"cell_towers\": [{\"location_area_code\": \""
        + lac + "\", \"mobile_network_code\": \"" + mnc
        + "\", \"cell_id\": \"" + cellId
        + "\", \"mobile_country_code\": \"" + mcc
        + "\"}], \"version\": \"1.1.0\", \"request_address\": \""
        + requestAddress + "\"}";

    URL anUrl = new URL("https://www.google.com/loc/json");
    HttpURLConnection conn = (HttpURLConnection) anUrl.openConnection();

    conn.setRequestMethod("GET");
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setUseCaches(false);
    conn.setAllowUserInteraction(false);
    conn.setRequestProperty("Content-type", "application/jsonrequest");

    OutputStream out = conn.getOutputStream();
    out.write(data.getBytes());
    out.close();

    InputStream in = conn.getInputStream();

    StringBuilder builder = new StringBuilder();
    Reader reader = new InputStreamReader(in);
    char[] buf = new char[1024];
    int read = 0;
    while ((read = reader.read(buf)) >= 0) {
        builder.append(String.valueOf(buf, 0, read));
    }
    in.close();
    conn.disconnect();

    double location[] = new double[2];
    try {
        JSONObject loc = new JSONObject(builder.toString()).getJSONObject("location");
        location[0] = Double.valueOf(loc.getDouble("latitude"));
        location[1] = Double.valueOf(loc.getDouble("longitude"));
    } catch (JSONException e) {
        location[0] = -1;
    location[1] = -1;
    }
    return location;
}

使用此新代码,请注意我使用的是Google Location JSON服务,它返回一个JSON对象。我应该说这是一个非常棘手的问题,我需要更多地搜索以了解所有的机制,但至少,这是一个有效的代码。希望它能帮到某人。

更新:我还希望在以下背景下完成此答案:三角测量通过移动网络(GSM,UMTS,LTE等等)使用无线电接入。我现在很清楚,这些价值因为无线电在环境(墙壁,建筑物,邻近的塔楼,等等)上有很多干扰的事实而来的