Запрос ближайшего местоположения с помощью GeoFire

Мне трудно понять, как GeoFire опрашивает близлежащие местоположения;

Я создаю географическое приложение, которое будет извлекать ближайшие местоположения в зависимости от местоположения пользователя. Мои данные структурированы следующим образом

locations
    -Ke1uhoT3gpHR_VsehIv
    -Kdrel2Z_xWI280XNfGg
        -name: "place 1"
        -description: "desc 1"
geofire
    -Ke1uhoT3gpHR_VsehIv
    -Kdrel2Z_xWI280XNfGg
        -g: "dr5regw90s"
        -l
            -0: 40.7127837
            -1: -74.00594130000002

Кажется, я не могу понять всю идею «ключей отслеживания» и местоположений, покидающих и входящих в GeoQueries. (Возможно, эта концепция больше связана с Uber-подобной функциональностью)

Предполагая, что locations выше находятся поблизости, как именно я могу использовать свои собственные координаты широты и долготы для их получения? Я уверен, что неправильно интерпретирую документацию GeoFires, но я просто не вижу этого.


person Clay Banks    schedule 04.03.2017    source источник
comment
После того, как вы вставите данные под ключ geofire с помощью Geofire, вы можете получить ключи в определенной области с помощью гео-запроса. Например var geoQuery = geoFire.query({ center: [10.38, 2.41], radius: 10.5 }); Этот пример и многое другое см. В документации Geofire: github.com/firebase/geofire-js/blob/master/docs/   -  person Frank van Puffelen    schedule 05.03.2017
comment
Спасибо @FrankvanPuffelen - это не указано в документации, но вернет ли это массив ключей в зависимости от радиуса?   -  person Kurai Bankusu    schedule 05.03.2017
comment
Нет, он не вернет массив. Firebase - это база данных реального времени, поэтому этот массив будет постоянно обновляться (что невозможно). Вместо этого он запускает события. Вы ознакомились с примерами? github.com/firebase/geofire-js/tree/master/examples   -  person Frank van Puffelen    schedule 05.03.2017
comment
Спасибо, Фрэнк, да, я проверял примеры много раз - думаю, я все еще привыкаю к ​​основам Firebase / GeoFire.   -  person Kurai Bankusu    schedule 05.03.2017
comment
Просто чтобы уточнить, события, как событие 'key_entered', необходимы для geoQuery, чтобы правильно определять близлежащие местоположения? Если да, то предоставленная вами строка: var geoQuery = geoFire.query({ center: [10.38, 2.41], radius: 10.5 }); на самом деле не будет содержать данные о ближайших местах сама по себе, а в сочетании с прослушивателями событий.   -  person Kurai Bankusu    schedule 05.03.2017
comment
@KuraiBankusu этот пост полезен. firebase.googleblog.com/2014/06/geofire-20.html   -  person vzhen    schedule 17.03.2017
comment
@KuraiBankusu, вам не нужно отслеживать каждый ключ самостоятельно. Цитата из сообщения выше. GeoFire is smart about how it looks for keys within the query. It does not need to load all of the GeoFire data into memory.   -  person vzhen    schedule 17.03.2017
comment
@vzhen Я понимаю, но тогда как бы вы добавили расстояние многих мест в радиусе к их соответствующим объектам огневой базы? Неужели для этого не нужны два отдельных массива?   -  person Kurai Bankusu    schedule 17.03.2017


Ответы (1)


Чтобы получить все местоположения, которые находятся поблизости, сначала мы получаем ссылку на базу данных, где мы сохраняем наши местоположения GeoFire. Судя по вашему вопросу, это должно быть

DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("geofire");

Затем мы создаем экземпляр GeoFire с нашей ссылкой на местоположение GeoFire в качестве аргумента.

GeoFire geoFire = new GeoFire(ref);

Теперь мы запрашиваем ссылку GeoFire, geoFire, используя его queryAtLocation метод. Метод queryAtLoction принимает 2 аргумента: объект GeoLocation и диапазон расстояний. Таким образом, если мы используем 3 в качестве диапазона расстояний, любое местоположение, находящееся на расстоянии 3 км от пользователя, будет отображаться в методе onKeyEntered(...).

NB: объект GeoLocation принимает 2 аргумента: широту и долготу. Таким образом, мы можем использовать широту и долготу пользователя в качестве аргументов.

        GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(userLatitde, userLongitude), 3);
        geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
            @Override
            public void onKeyEntered(String key, GeoLocation location) {
                //Any location key which is within 3km from the user's location will show up here as the key parameter in this method 
                //You can fetch the actual data for this location by creating another firebase query here
    Query locationDataQuery = new FirebaseDatabase.getInstance().child("locations").child(key);
    locationDataQuery..addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            //The dataSnapshot should hold the actual data about the location
    dataSnapshot.getChild("name").getValue(String.class); //should return the name of the location and dataSnapshot.getChild("description").getValue(String.class); //should return the description of the locations
                        }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
            }

            @Override
            public void onKeyExited(String key) {}

            @Override
            public void onKeyMoved(String key, GeoLocation location) {}

            @Override
            public void onGeoQueryReady() {
                //This method will be called when all the locations which are within 3km from the user's location has been loaded Now you can do what you wish with this data
            }

            @Override
            public void onGeoQueryError(DatabaseError error) {

            }
        });
person Aryeetey Solomon Aryeetey    schedule 28.05.2017
comment
Не могли бы вы рассказать, как мы можем быть уведомлены, когда все наши фактические данные (не геоданные) получены и мы можем уведомить переработчика, или это нормально сделать это в public void onDataChange(DataSnapshot dataSnapshot)? - person Levon Petrosyan; 06.04.2018
comment
onDataChange(DataSnapshot dataSnapshot) вызывается только в том случае, если все данные были загружены. Вы загружаете список предметов? - person Aryeetey Solomon Aryeetey; 06.04.2018
comment
Но мы вызываем onDataChange(DataSnapshot dataSnapshot) в onKeyEntered(String key, GeoLocation location) обратном вызове, который может срабатывать несколько раз, поэтому для каждого будет вызываться key onDataChange(DataSnapshot dataSnapshot), и я хотел бы добавить каждый объект data в свой recyclerview - person Levon Petrosyan; 06.04.2018