2

これはやや大雑把ですが、ここで説明します。三角形分割アルゴリズムで非常に奇妙な問題が発生しています。時々、正しい緯度/経度が返され、しばらくすると間違った緯度/経度が返されます。さらに奇妙なのは、このエラーがいつ発生するかを予測することも、再現することもできないことです。コードの行を変更しなくても発生します (正しい値を受け取り、次に間違って、次に訂正する...)。

Google GLM サービスを使用して、デバイスの LAC (ロケーション エリア コー​​ド) とタワー 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 に保存し、それをすべてのビューで使用します。

間違ったアルゴリズムでメソッドを実装したのか、プロセスに見逃したトリックがあるのか​​ 疑問に思っています。現在、私の正しい近似緯度/経度値は緯度 = -23および経度 = -46ですが、(時々)緯度 = 17および経度 = 81の値を受け取っています。誰かが何が起こっているのかについてのヒントを教えてもらえますか?

4

1 に答える 1

0

大丈夫。私は自分で解決策を見つけました。どうぞ。三角測量プロセスは、基本的に 3 つの引数の組み合わせプロセスです。私が行ったいくつかの検索に基づいて、さまざまな種類のデータの組み合わせを使用できると推測します。私が使用した組み合わせは、タワー 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;
}

この新しいコードでは、JSON オブジェクトを返す Google Location JSON サービスを使用していたことに注意してください。これは非常にトリッキーな問題であり、すべてのメカニズムを理解するためにさらに検索する必要があると言わざるを得ませんが、少なくとも、これは機能するコードです。それが誰かを助けることを願っています。

更新: また、次のコンテキストでこの回答を完成させたいと思います: TRIANGULATION USES RADIO ACCESS THROUGH MOBILE NETWORK (GSM, UMTS, LTE, AND SO ON). これらの値の変動は、電波が環境 (壁、建物、近隣の塔など) に対して多くの干渉を及ぼすという事実から来ていると確信しています。

于 2012-08-21T17:48:37.330 に答える