Страницы

Поиск по вопросам

Показаны сообщения с ярлыком gps. Показать все сообщения
Показаны сообщения с ярлыком gps. Показать все сообщения

пятница, 13 марта 2020 г.

Android. Фильтрация GPS данных, какую погрешность считать за норму?

#android #gps


Хотел найти пример приложения с удачного реализованным фильтром GPS-данных, скачал
два популярных трекера MyTracks, Open GPS Tracker. Первый разработали сами гугловцы. 
Запускаю, оба трекера выписывают кренделя и насчитывают киллометры, когда телефон
лежит на месте(за 20 минут первое приложение насчитало 2.5км второе 1.9км, третье без
фильтров 4.5км). Сервис Traccar на демо сервере без доп настроек 3.7 км. Да телефон
дешовый и GPS тоже, но все равно: 


Все на самом деле так плохо? Считать эту погрешность нормой или у
разработчиков были руки кривые?  
При движении на авто какую погрешность считать нормой?


P.S. Все очень относительно, но может найдется человек, который собаку съел на этом
деле и определился с нормами в построении маршрутов.
    


Ответы

Ответ 1



У разработчиков руки нормально. Только все телефоны по разному определяют координаты. И еще это зависит от погоды, здании где вы сидите и т.п. Так что если программа работает на улице нормально, это норма. Если на авто берите каждые 200 метров. Так лучше. И еще попробуйте фиксировать координаты при: каждые 200 метров если угол поворота авто больше 15 С если не движется фиксация каждую минуту. еще попробуйте программу от https://www.traccar.org/ Traccar (Server): git clone https://github.com/tananaev/traccar.git Traccar Client for Android: git clone https://github.com/tananaev/traccar-client-android.git Traccar Client for iOS: https://github.com/tananaev/traccar-client-ios.git

вторник, 28 января 2020 г.

Получение текущих GPS координат

#android #java #gps


Как запросить текущие GPS координаты устройства? Я видел функцию getLasKnownLocation
но ее название и применение говорит само за себя. Требуется получать (запрашивать у
модуля) текущую локацию телефона    


Ответы

Ответ 1



Примерно так: public class MyLocationActivity extends Activity implements LocationListener { private static final String TAG=MyLocationActivity.class.getName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } @Override public void onLocationChanged(Location location) { if (location != null) { Log.d(TAG, "Широта="+location.getLatitude()); Log.d(TAG, "Долгота="+location.getLongitude()); } } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } } Только надо озаботиться соотвествующими пермишеном в манифесте

четверг, 2 января 2020 г.

Диалог с предложением включить GPS

#android #gps


Когда заходишь в Google Maps и у тебя выключен GPS, Андроид тебе предложит включить
его диалогом с двумя кнопками. При нажатии на ОК - GPS включится.

Как сделать такой же диалог в своем приложении ?

И да, я правильно понимаю, что программно я никак не могу включить GPS без спрашивания
пользователя ?
    


Ответы

Ответ 1



Опросите систему включен ли GPS. public boolean isGeoDisabled() { LocationManager mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); boolean mIsGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean mIsNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); boolean mIsGeoDisabled = !mIsGPSEnabled && !mIsNetworkEnabled; return mIsGeoDisabled; } если нет, покажите диалог с предложением включить, при согласии отправьте пользователя в настройки startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));

Ответ 2



Программно включить без согласия пользователя вы не сможете. Диалог можно реализовать например вот так: private LocationManager locationManager; public static boolean geolocationEnabled = false; /** * Проверяет включены ли соответствующие провайдеры локации */ private boolean checkLocationServiceEnabled() { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); try { geolocationEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch (Exception ex) { } return buildAlertMessageNoLocationService(geolocationEnabled); } /** * Показываем диалог и переводим пользователя к настройкам геолокации */ private boolean buildAlertMessageNoLocationService(boolean network_enabled) { String msg = !network_enabled ? getResources().getString(R.string.msg_switch_network) : null; if (msg != null) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setCancelable(false) .setMessage(msg) .setPositiveButton("Включить", new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); } }); final AlertDialog alert = builder.create(); alert.show(); return true; } return false; } Затем использовать как проверку в OnResume у активити: checkLocationServiceEnabled();

суббота, 7 декабря 2019 г.

Получение местоположения пользователя

#android #gps #карты


При запуске приложения требуется получить местоположение пользователя на карте. Погуглив
и посмотрев в книге, единственное, что я нашел — это использовать слушатель смены расстояния:

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            //Получаю местоположение и отписываюсь
            locationManager.removeUpdates(this);
            ...
        }
   ...
}


Такой способ не всегда работает. Иногда приложение ждет 10 секунд-2 минуты, прежде
чем слушатель сработает. Иногда просто не срабатывает (если телефон не двигается).



Есть какая-то 100% работающая альтернатива запросить текущее расстояние (при условия
нормальной работы GPS), а не ждать ответа в слушатель изменения?
    


Ответы

Ответ 1



Почему вы запрашиваете в провайдере именно GPS_PROVIDER? GPS долго прогревается при холодном старте и из-за этого возникают задержки в 20-120 секунд. Если использовать координаты сети/Wi-Fi, то локацию можно получить почти моментально. Попробуйте reactive-location, там есть пример получения локации с таймаутом, получится хороший флоу для Вашего случая: LocationRequest req = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setExpirationDuration(5000) .setInterval(1000); Observable goodEnoughQuicklyOrNothingObservable = new ReactiveLocationProvider(getContext()) .getUpdatedLocation(req) .filter(location -> location.getAccuracy() < 50) // с точностью до 50 метров .timeout(5, TimeUnit.SECONDS, Observable.just(null), AndroidSchedulers.mainThread()) .first() .observeOn(AndroidSchedulers.mainThread()); Subscription subscription = goodEnoughQuicklyOrNothingObservable .subscribe(location -> { if (location == null) { // не удалось получить координаты, // требуется ввод вручную } else { // получили координаты } }, Timber::e);

Ответ 2



Спустя неделю поисков и вопроса на enSO и ruSO, я пришел к варанту, что альтернатив - нет. Местоположение можно определить только с помощью LocationManager.requestLocationUpdates и получить последнее местоположение, которое запомнил телефон методом FocusedLocationProviderApi. Как альтернативу, можно предложить пользователю выбрать местоположение через маркер или ввести вручную. В этом помогут автоввод местоположения и определение местоположения через координаты.

Ответ 3



В качестве альтернатив можно предложить разве что ручной ввод местоположения. Еще было бы хорошо требовать от пользователя включения Wi-Fi, для более точного позиционирования. Да и получение координат через Wi-Fi/A-GPS будет работать гораздо быстрее - моментально даже. Ведь в отличии от GPS не тратиться время на поиск спутников.

воскресенье, 1 декабря 2019 г.

Среднее значение из бесконечно поступающих данных

#алгоритм #gps


Пишу программу gps навигатор, есть функция - средняя скорость. 

Данные поступают постоянно и все значения записывать не вариант. У меня была идея
записывать определенное количество значений, скажем, 50 и из них строить среднюю скорость.

У кого-нибудь есть предложения или может кто-то сталкивался с подобным, как вы решили
проблему?
    


Ответы

Ответ 1



Допустим avg - среднее арифметическое из n измерений. Появляется следующее измерение a. Чтобы учесть это измерение достаточно пересчитать среднее avg = avg * (n / (n + 1)) + a / (n + 1). Таким образом вам достаточно хранить только среднее и количество учтенных в нем измерений. Только мне кажется, что для вашей задачи нужно будет сделать хитрый ход: ограничить выборку последними m - значениями. Насколько я понял, вы считаете среднюю скорость, чтобы "сгладить" резкие скачки при отображении скорости. Тогда можно принять n за константу ( n = m ) и таким образом каждый раз отбрасывать из расчета среднего измерение равное "предыдущему" среднему. Дополнено Для последнего случая необходимо получить среднее значение для начального участка. Тут можно пойти двумя путями: Задать avg равным первому измерению; Наращивать n от нуля до m. Приведу пример: double getAvg(double aNext, int m) { static double avg = 0; static double n = 0; avg = avg * (n / (n + 1)) + aNext / (n + 1); n += 1; if (n > m) n = m; return avg; }

Ответ 2



Средняя скорость обычно привязывается к некоторому характерному времени задачи, а данные из совсем далёкого прошлого обычно портят оценку. В то же время есть простой способ копить данные с экспоненциальныо убывающим весом, когда рекуррентно накапливаются две суммы: Q' = 1 + q Q, V' = v + q V. При этом vср = V' / Q'. Нетрудно убедиться, что данные накапливаются с весами, представляющими собой бесконечно убывающую в сторону прошлого геометрическую прогрессию. Выбирая q = 1 - 1/N, мы тем самым задаём вес exp(-1) = 0,37 для данных, удалённых на N отсчётов в прошлое. При этом Q <= 1 / (1-q) = N, V <= vmax*N.

Ответ 3



Если для GPS, разве нельзя рассчитать среднюю скорость исходя из длинны пути и прошедшего времени? т.е. Вам достаточно хранить пройденное расстояние и пройденное время от начала маршрута.

вторник, 16 июля 2019 г.

Проверить включен ли GPS на Android

Воспользовался этим решением
public static boolean isLocationEnabled(Context context) { int locationMode = 0; String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ try { locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (SettingNotFoundException e) { e.printStackTrace(); }
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
}else{ locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); return !TextUtils.isEmpty(locationProviders); } }
Но этот метод всегда возвращает true, не зависимо включен или выключен GPS


Ответ

Посмотрите в сторону LocationManager
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);; boolean enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); //enabled true если включен GPS
Ну и не забудьте о пермишене в манифесте:

понедельник, 8 июля 2019 г.

Нужен совет по написанию игры с постоянным подключением к GPS [закрыт]

Здравствуйте, я собираюсь написать некое подобие игры Pokemon GO. Вместо покемонов обычные точки (на выбор 30), выбрал одну, остальные исчезают, показываются другие игроки, идущие к ней. Успел, пришел, подтвердил местоположение, получил опыт. Не успел, пришел кто-то другой, не получил опыт. Это получается, что подключение к GPS спутникам будет беспрерывное! Беспрерывно должны отправляться координаты игрока, чтобы у других не писались ложные данные. Беспрерывно должен обновляться статус точки (пришли, не пришли). А ведь на улице зарядного устройства нет, а power бланки не у всех имеются, да и телефон будет нагреваться.
Что можно сделать? У меня несколько вопросов в плане реализации
1) Нужно что-то супер точное, чтобы местоположение было максимально правильным
2) Нужно сделать сервис игры безобидным, очень волнуюсь за батареи игроков
3) Если игрок получит травмы, засмотревшись на экран или побежав к точке на дорогу или в чужой дом? Нужно будет лицензионное соглашение?
4) Не забанят ли в GP? Не видел там покемон го, и вообще других аналогов


Ответ

Супер точное местоположение это миф (в Google Maps), даже в Pokemon Go порой разброс большой. Опять же на примере Pokemon Go, батарея улетает очень быстро, а из функций, относящихся к сохранению батареи, только лишь заставка с затемненным экраном, когда опускаешь телефон - то бишь сенсор. В Pokemon Go порой выскакивают диалоги с надписями типа: "Не играйте за рулем", "Смотрите по сторонам". Лиц. соглашение обязательно нужно будет писать т.к. собираетесь хранить местоположение игроков на своем сервере. Не должны
P.S. А вообще трудности будут не сколько с батареей, а с борьбой фейк местоположения. Данный труд выстрелит до первых отзывах о читерах.

Из географических координат в локальные

Описание:
Есть координаты объектов в формате возвращённым Google Api. То есть широта, долгота и т.п.
Например у меня 3 объекта, берём объект (1) его локальные координаты становятся [0,0]. Объект (2) находится на 5 метров на север и 2 метра на восток относительно объекта (1), его координаты должны стать [5,2]. Объект номер (3) находится на 75 метров на юг и на 35 метров на запад, его координаты должны стать [-75, -35].
Вопрос:
Как перевести объекты в локальную систему координат зная их широту и долготу, пожалуйста помогите?
Видимые решения:
Появилась мысль получить расстояние между объектами при помощи следующего решения. (однако тут точность в км, как можно повысить до метров?) И после этого вычислить угол между географической координатой северного полюса, объекта (1) (который взят за [0,0] в локальных) и объекта (2) и уже зная дистанцию и угол рассчитать координату объекта (2) в локальных координатах. Будет ли искажение у угла, если я применю подобные вычисления? Земля же не квадратная
P.S. Надо вычислять на телефоне, и таких вычислений будет до 50 шт за раз, а то и больше, желательно максимально оптимальное решение, но важна точность вплоть до 1 метра. (Подобные вычисления на телефоне вызывают у меня опасения)
P.P.S. Можете пожалуйста предоставить код на C# решения данного вопроса?
P.P.P.S. По идеи это всё похоже на систему где объект (1) - это человек, и требуется рассчитать в метрах положение объектов в локальных координатах (метрах). Однако я не смог найти, как это реализовано в gps навигаторах.


Ответ

Точность позиционирования определяется точностью координат. Если Google возвращает тебе километры, значит будут километры. Возвращает метры - будут метры.
Да, разумеется, искажения будут. Прочитай про проекции координат на плоскость. Выбирай что тебе больше нравится - равноугольные, равновеликие или какие-нибудь ещё.
После того, как ты переведёшь географические координаты в координаты на плоскости, вычесть y/x одного объекта из другого для тебя не составит труда.
Пока чисел меньше 1 000 000 ты можешь использовать любое решение, потерь скорости ты не заметишь, больше потратишь на отображение.
Есть готовое решение на все случаи жизни, не обязательно изобретать собственный велосипед.

четверг, 28 марта 2019 г.

Получение текущих GPS координат

Как запросить текущие GPS координаты устройства? Я видел функцию getLasKnownLocation но ее название и применение говорит само за себя. Требуется получать (запрашивать у модуля) текущую локацию телефона


Ответ

Примерно так: public class MyLocationActivity extends Activity implements LocationListener { private static final String TAG=MyLocationActivity.class.getName();
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); }
@Override public void onLocationChanged(Location location) { if (location != null) { Log.d(TAG, "Широта="+location.getLatitude()); Log.d(TAG, "Долгота="+location.getLongitude()); } }
@Override public void onProviderDisabled(String provider) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onStatusChanged(String provider, int status, Bundle extras) { } } Только надо озаботиться соотвествующими пермишеном в манифесте

пятница, 11 января 2019 г.

Диалог с предложением включить GPS

Когда заходишь в Google Maps и у тебя выключен GPS, Андроид тебе предложит включить его диалогом с двумя кнопками. При нажатии на ОК - GPS включится.
Как сделать такой же диалог в своем приложении ?
И да, я правильно понимаю, что программно я никак не могу включить GPS без спрашивания пользователя ?


Ответ

Опросите систему включен ли GPS.
public boolean isGeoDisabled() { LocationManager mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); boolean mIsGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean mIsNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); boolean mIsGeoDisabled = !mIsGPSEnabled && !mIsNetworkEnabled; return mIsGeoDisabled; }
если нет, покажите диалог с предложением включить, при согласии отправьте пользователя в настройки
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));

среда, 5 декабря 2018 г.

Погрешности GPS и варианты борьбы с ними

Стоит задача подсчета метров по GPS на малой скорости движения (3-5км/ч) и соответственно на малых расстояниях (от 0.5 метра и выше). При реализации задачи получаем огромную погрешность (20-100 метров) между изменениями координат (когда вызывается onLocationChanged каждую секунду). Понятно, что GPS-приемник в смартфоне слабее и сама точность от спутника не супер, но может кто-то знает как можно улучшить точность расчетов, какой-либо алгоритм или вообще какие-либо интересные особенности, сторону в которую стоит копать? Я пока не уверен, что на малых расстояниях задача впринципе реализуема :( Возможно потому что нужно уйти в дебри навигации.


Ответ

Единственное решение, которое пока что удалось найти - так это поиск мат ожидания от всех получаемых координат за каждую секунду. Результат становится чуть более сглаженным. Также, думаю стоит добавить какие-либо условия на допустимые границы: к примеру мы знаем скорость движения или предполагаем, что человек идет и так как координаты мы получаем каждую секунду, то примерные изменения мы можем отфильтровать, задействовав к тому же датчики. Пока что так.