Monday, December 9, 2013

Firebase map

How to mapped fields in firebase storage to map in webbrowser?

What do we need?

1.Initial load with listener.
2. catch changes
3. move camera or zoom - create and remove fields and listener

Many fields in a few queries

I started with idea, that i should load so much data as possible (Whole displayed fields and one listener on it).

Example:
I am looking to position [2,2]. So i need a radius for instance 1 field around it. That means I want to load field ([1,1],...,[3,3]) = 9 fields.
You can Querying and Limiting Data (by priority, element.name). But with these parametres you can select only one collum. If we insert into firebase elements with priority X and name Y :

firebaseRef.startAt(1, 'x1').endAt(1, 'x4').on('value', cb); //select fields [1,1]..[3,1]

There are three queries (for each row) with principe we mention above, which  give us Example result.

But ideal is to ask only one for the whole rectangle of data. So i was looking for some other solution and i found Geohash. There is also JS api for using geohash in firebase. It is callled geoFire (introduce article in firebase web). GeoFire (geoHash) works with GPS locations but we are using 2D locations. So we will create a new class based on GeoFire. In geoFire is function for get fields, but we have to create new one to catch only fields which were changed. Interface of geoFire satisfies our requiest (one ask for whole rectangle). When you look at the implementation you find out that there is in worth case as queries as fields we we wanted.

1. initial load cost
- in worst case n*ASK (in best way only one)
- n*create listener (in best way only one)
- loads c*n fields
where n is num of fields and c is constant for number of fields with same prefix

2. catch changes cost
- only changed field is load

3. move camera or zoom - create and remove fields and listener cost
- remove fields no ask or load
- remove listener on whole area - in worst case for each fields - N unloads (in best way only one)
- in worst case n*ASK (in best way only one)
- n*create listener (in best way only one)
- loads c*n fields

A field in many queries

Simply solution is ask for each fields to firebase and sets Listener for each fields too.

Structure in firebase for this case could be fields/x/y.

1. initial load cost
- n*ASK
- n*create listener
- loads n fields
where n is num of fields

2. catch changes cost
- only changed field is load

3. move camera or zoom - create and remove fields and listener cost
- remove fields no ask or load
- remove listener only from remove fields (W)
- W*ASK
- W*create listener
- loads W fields

So very important is question whether many simple ASKs is slower then one big ASK. Then for high N and W near to N should be better use "Many fields in a few queries" technique otherwise "A field in many queries".

Here is a answer. Data size and network bandwidth are the consideration here, not the number of connections. So my testing:
100* 
9 fields with unload (each field separately)
-The first fields come in 900ms and the last in 2,600ms.
all in one
-The first fields come in 1600ms and the last in 1900ms.

Some other features for our map

Zoom
Our Isoengine supports zoom. We will trigger zoom on mouse roll button.

Loading map dynamically
We have a big map. We will need to slide to next fields. We will load fields dynamically. 
When user overcome boundry, we will give him new data from firebase and set new boundry.
For better efficiency we will destroy fields out of the boundry.

Caching fields in browser
There is also option don´t destroy whole out of view field, but only destroy it from canvas. It will save a data transfer.

No comments:

Post a Comment