Неверная позиция получена при триангуляции в Android

Это несколько широко, но начнём: у меня возникла очень странная проблема с моим алгоритмом триангуляции. Иногда он возвращает правильную широту/долготу, а затем, через некоторое время, возвращает неправильную широту/долготу. Еще более странно то, что я не могу предсказать, когда произойдет эта ошибка, и не могу ее воспроизвести. Это происходит, даже если я не меняю строки в своем коде (получаю правильные значения, затем неправильные, затем правильные и т. д.).

Я использую службу Google GLM, отправляю LAC устройства (код зоны местоположения) и идентификатор башни, чтобы определить мое положение треугольником. Основной метод моего алгоритма заключается в следующем:

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 и вызывается с задержкой в ​​1 минуту через PendingIntent. Вызывающий его поток сохраняет значения широты и долготы в SharedPreferences, а затем я использую их во всех своих представлениях.

Мне интересно, реализовал ли я метод с неправильным алгоритмом или есть ли в процессе какой-то трюк, который я пропустил. В настоящее время мои правильные приблизительные значения широты и долготы: широта = -23 и долгота = -46, но я получаю (иногда) значения широты = 17 и долгота = 81. Может ли кто-нибудь дать мне подсказку о том, что происходит?


person Marcelo    schedule 15.08.2012    source источник


Ответы (1)


Хорошо. Я нашел решение самостоятельно. Вот так. Процесс триангуляции в основном представляет собой процесс комбинации трех аргументов. На основе некоторых поисков, которые я сделал, я пришел к выводу, что вы можете использовать различные типы комбинаций данных. Комбинация, которую я использовал, представляет собой смесь идентификатора вышки (трансивер вышки, с которым устройство рукопожато), кодов местоположения (код города и код страны) и кода региона местоположения. Итак, мой новый код выглядит следующим образом:

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 И Т.Д.). ТЕПЕРЬ Я ПОЧТИ УВЕРЕН, ЧТО ЭТИ КОЛЕБАНИЯ ЗНАЧЕНИЙ ПРОИСХОДЯТ ИЗ-ЗА ТОГО, ЧТО РАДИОВОЛНЫ СИЛЬНО ВОЗДЕЙСТВУЮТ НА ОКРУЖАЮЩУЮ СРЕДУ (СТЕНЫ, ЗДАНИЯ, СОСЕДНИЕ БАШНИ И Т. Д.)

person Marcelo    schedule 21.08.2012