I am making an app which downloads LatLngs from firebase and shows them as markers in google maps API, users can add new LatLngs.
In my database I also have the pricepoint and types of markers. In the main screen the user can choose what types of marker he wants to see on the map.
So my application does something like this:
locations.orderByChild(pricepoint).equalTo(choosenPricepoint);
and then I check programmatically if types match those chosen by the user
int type = Integer.parseInt(locations.child("restaurantType").getValue().toString();
if(type == funCode|| type == runingCode|| type == sportsCode
{
mMap.addMarker(new MarkerOptions().position(snapshot.getLatlng);
}
And it works fine with 250 records, but I'm expecting over 10,000 of them in my database so I am worried that it will be too slow.
I don't know if showing markers only where user's maps camera is and deleting other will be faster. What do you suggest?
You can use GeoFire , a firebase library that uses GeoHashes to merge lat+lon into a single property.That way you can do the distance filtering directly on the database.
You should have 2 entries in firebase database,one for setting your object location and one for setting your object with its fields.
As you can see they have the same id.So first you are queriing for nearby object by GeoFire in geo_data entry,and you will get the ids of the object which are nearby,then you can retreive object with its properties directly from database using the ids in my case in user_data entry
Related
I'm making an android app where user can find a book in his/her vicinity and buy it if interested. I am using firebase and geoqueries/geofire.
I want to make a SearchActivity where user can search a book by it's title in his/her vicinity.
my Firebase Database Structure looks like :
books
PushKey
g:
l:
0:
1:
name:"some book name"
If i try to query this with some book name, it works fine using :
myRef.orderByChild("name").equalTo("some book name").addChildEventListener()....//The rest of the code here...
If i try to query nearby books,then also it works fine using :
geoQuery = geoFire.queryAtLocation(myLocation, 10);
I'm stuck at combining these two.
How can i search for a specific book name only in the vicinity?
For example : I want to search a book whose name is "ABCD" and is in a radius of 10km.
OR
Search a book by name and tell which one is nearest(In case several books are uploaded with same name at different locations).
Is it possible to do so? If not, what workaround(maybe other than firebase, but has to cheap and affordable) can i opt for where i can achieve this desired result?
The Firebase Database can only query by a single property. The fact that GeoFire does something that is seemingly at odds with that (querying by longitude and latitude) is because it combines these values into a single property in a magical format called a geohash (the g property in your JSON).
Combining values into a single property is the only way to get Firebase to filter on multiple values. For example, you could prefix the g property with your book title to get some book name_geohashvalue and could then filter on that.
The two main problems with that:
This only works if you know the entire book title, you can do a prefix match on the title, as you'll already need to use the prefix match for the geohash.
This is not built in to GeoFire, so you will have to fork that library and build it yourself.
If you do try to do this yourself, and get stuck, we can try to help. But fair warning: this won't be trivial, and you'll need to understand how geohashes, geofire, and Firebase's query model work quite well. For an intro, I recommend watching the video of my talk on performing geoqueries on Firebase and Firestore.
If you want something a bit less involved, you have two main options:
Retrieve all nodes within range, and then filter for the book title client-side.
Store a separate GeoFire tree for each book title, so that you can initialize your GeoFire object based on the book title, and only get keys within range for that specific book title.
Between these two, I'd recommend starting with #1.
I implemented Skobbler SDK in my app to navigate offline maps. I have an issue while trying to get coordinates from an address when user is offline. Even if I have installed the package relative to the city in which I am trying to navigate, when I start multi-step search it returns empty results without the possibility to understand what I am doing wrong because there is no way to manage eventual error messages. Here is my code as reported in Skobbler docs:
private void searchAtCurrentLevel(long parentId, SKSearchManager.SKListLevel level) {
// get a search manager object
SKSearchManager mgr = new SKSearchManager(this);
// get a multi-step search object
SKMultiStepSearchSettings searchSettings = new SKMultiStepSearchSettings();
// set the offline package in which to search
searchSettings.setOfflinePackageCode(code);
// set list level of the search
searchSettings.setListLevel(level);
// set maximum number of results to be received
searchSettings.setMaxSearchResultsNumber(20);
// set the id of the parent in which to search
searchSettings.setParentIndex(parentId);
// set a filter for the results
searchSettings.setSearchTerm("");
// initiate the search
mgr.multistepSearch(searchSettings);
}
where "code" is relative to the code of the city that I am into (for example GBCITY04 for London) and parentId is -1 like shown in Skobbler's Android "How To". I also tried to enter all different listLevel values but nothing changed.
In my app, I avoided to download "Maps.json" file because I have to manage only 2 cities, Milan and London, so i download only Milan and London's maps having relative city codes (ITCITY01 and GBCITY04). Can this be the cause of my problems?
Thanks in advance for the support.
I have an app in which I manually added some Markers to a google map. Then I saved the Markers to local storage. Now I want to re-run the app, load the set of markers and place them on the (now empty) map. I had assumed that there would be a method something like:
googleMap.addMarker(marker_I_loaded_from_memory), but I can't find it. Alternatively I thought there may be something like marker_I_loaded_from_memory.AddMyselfToMap(), but I can't find that either. Does either exist?
Edit: I am using maps API v 2
You cannot serialize Marker objects. They are connected with current view.
I suggest storing the relevant data in local DB. A table with latitude, longitude, title, etc. will do.
When recreating such Markers, use GoogleMap.addMarker(MarkerOptions), where MarkerOptions is constructed from the data in DB.
I have an activity that displays a list on markers based on the state of a model.
Whenever the model's state is changed, the markers are refreshed to display the new location or display any new markers.
I want to test this behavior but GoogleMap does not provide a .getMarkers() method or similar to know which markers are shown on the map.
The question is, how can I test both the number of Markers and the LatLng or each marker.
keep an ArrayList of all plotted markers and iterate through to find the one you want?
or there is a 3rd party mapping library that you can call getMarkers, getPolygons etc..
Thats just an idea but you can store you marker (latlng, id, image, etc) on an ArrayList. Then when you create your marker, assign foreach the id and on click retrieve the id to get all information's from your Array.
I am trying to implement a data structure which allows me to keep track of an index (so I can blindly access the data points), a key (which needs to be there to identify the data in the rest of the program), and a value.
I've looked at a map, but that does not allow me to access the data points without any key. I need some combination of a Queue and a Map. Does this exist and I'm just missing it? Thanks for the help.
I believe what you are looking for is a LinkedHashMap. It will return an ordered collection and you can access values via a key.
LinkedHashMap<Key, Value> myMap = new LinkedHashMap<Key, Value>();
myMap.put(aKey, aValue); //adds to map.
myMap.values(); //returns collection of values
aValue = myMap.get(Key); //returns a value with the given key