├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── imperiumlabs │ │ └── geofirestoreexample │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── imperiumlabs │ │ │ └── geofirestoreexample │ │ │ └── MainActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── org │ └── imperiumlabs │ └── geofirestoreexample │ └── ExampleUnitTest.java ├── build.gradle ├── docs ├── allclasses-frame.html ├── allclasses-noframe.html ├── constant-values.html ├── deprecated-list.html ├── help-doc.html ├── index-files │ ├── index-1.html │ ├── index-10.html │ ├── index-11.html │ ├── index-12.html │ ├── index-13.html │ ├── index-14.html │ ├── index-15.html │ ├── index-16.html │ ├── index-17.html │ ├── index-18.html │ ├── index-19.html │ ├── index-2.html │ ├── index-3.html │ ├── index-4.html │ ├── index-5.html │ ├── index-6.html │ ├── index-7.html │ ├── index-8.html │ └── index-9.html ├── index.html ├── org │ └── imperiumlabs │ │ └── geofirestore │ │ ├── ExampleInstrumentedTest.html │ │ ├── ExampleUnitTest.html │ │ ├── GeoFirestore.CompletionListener.html │ │ ├── GeoFirestore.LocationCallback.html │ │ ├── GeoFirestore.html │ │ ├── GeoLocation.html │ │ ├── GeoQuery.html │ │ ├── GeoQueryDataEventListener.html │ │ ├── GeoQueryEventListener.html │ │ ├── core │ │ ├── GeoHash.html │ │ ├── GeoHashQuery.Utils.html │ │ ├── GeoHashQuery.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ └── package-tree.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── util │ │ ├── Base32Utils.html │ │ ├── Constants.html │ │ ├── GeoUtils.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── overview-frame.html ├── overview-summary.html ├── overview-tree.html ├── package-list ├── script.js └── stylesheet.css ├── geofirestore ├── .gitignore ├── build.gradle ├── lint.xml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── imperiumlabs │ │ └── geofirestore │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── imperiumlabs │ │ │ └── geofirestore │ │ │ ├── AndroidEventRaiser.kt │ │ │ ├── EventRaiser.kt │ │ │ ├── GeoFirestore.kt │ │ │ ├── GeoLocation.kt │ │ │ ├── GeoQuery.java │ │ │ ├── ThreadEventRaiser.kt │ │ │ ├── core │ │ │ ├── GeoHash.kt │ │ │ └── GeoHashQuery.kt │ │ │ ├── extension │ │ │ ├── CollectionExtension.kt │ │ │ └── GeoFirestoreExt.kt │ │ │ ├── listeners │ │ │ ├── EventListenerBridge.kt │ │ │ ├── GeoQueryDataEventListener.kt │ │ │ └── GeoQueryEventListener.kt │ │ │ └── util │ │ │ ├── Base32Utils.kt │ │ │ ├── Constants.kt │ │ │ └── GeoUtils.kt │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── org │ └── imperiumlabs │ └── geofirestore │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea/* 5 | .DS_Store 6 | /build 7 | /captures 8 | /gen 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | ## [Unreleased] - 5 | ### Added 6 | - Methods in GeoUtils to convert a radius in m or km 7 | - The ability to pass a filter query to GeoQuery in order to filter the documents obtained in the query 8 | - Some Unit Test class 9 | 10 | ### Changed 11 | - Converted the GeoQuery class to Kotlin 12 | - GeoQuery constructor work with a radius in km and without the need to cap-it 13 | - GeoLocation constructor accept a GeoPoint 14 | - Updated some external dependency 15 | 16 | ### Removed 17 | - Ability to get the Firestore query(s) from the GeoQuery 18 | 19 | ## [v1.5.0] - 2019-06-24 20 | ### Added 21 | - Ability to parse document with "g" as List or GeoPoint 22 | - Added this CHANGELOG.md 23 | - method getAtLocation to GeoFirestore replacing the SingleGeoQuery class 24 | - SingleGeoQueryDataEventCallback to GeoFirestore 25 | 26 | ### Changed 27 | - Reorganized the entire project structure 28 | - Type of the "g" parameter from List to GeoPoint 29 | - The SingleGeoQuery is a method in the GeoFirestore class 30 | - Updated the README.md with the newest features 31 | - Changed package "callbacks" to "listeners" 32 | 33 | ### Removed 34 | - SingleGeoQuery class 35 | - SingleGeoQueryDataEventCallback 36 | 37 | ## [v1.4.0] - 2019-05-22 38 | ### Added 39 | - Ability to make a "one-shot" geo query using SingleGeoQuery 40 | 41 | ### Changed 42 | - Moved all the callbacks in to a separate package "/callbacks" 43 | 44 | ### Fixed 45 | - Build failure of v1.3.0 46 | 47 | ## [v1.3.0] - 2019-03-28 48 | Most of the classes are converted to Kotlin 49 | 50 | ### Added 51 | - Method setLocation accept Kotlin's lambda function 52 | - Method getLocation accept Kotlin's lambda function 53 | - Method removeLocation accept Kotlin's lambda function 54 | - Ability to get the Firestore query(s) from the GeoQuery 55 | 56 | ### Fixed 57 | - Geo Hashing algorithm 58 | 59 | ### Changed 60 | - Migration to AndroidX 61 | 62 | ## [v1.2.1] - 2019-02-26 63 | ### Removed 64 | - GeoQuery throw assertionError 65 | 66 | ## [v1.2.0] - 2019-02-26 67 | ### Fixed 68 | - issue with handle being null 69 | 70 | ### Updated 71 | - firestore dependency 72 | 73 | ## [v1.1.1] - 2018-07-11 74 | ### Fixed 75 | - Small changes to README.MD 76 | 77 | ## [v1.1.0] - 2018-07-10 78 | ### Fixed 79 | - Small changes to README.MD 80 | 81 | ## [v1.0.0] - 2018-07-10 82 | ### Fixed 83 | - Small changes to README.MD 84 | 85 | ## [v0.1.0] - 2018-07-10 86 | First version. 87 | 88 | ### Added 89 | - All the core functionality -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Imperium Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | google-services.json 3 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android-extensions' 3 | apply plugin: 'kotlin-android' 4 | 5 | android { 6 | compileSdkVersion 28 7 | defaultConfig { 8 | applicationId "org.imperiumlabs.geofirestoreexample" 9 | minSdkVersion 15 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | multiDexEnabled true 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(include: ['*.jar'], dir: 'libs') 26 | 27 | //Kotlin 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 29 | 30 | //Andridx 31 | implementation 'androidx.appcompat:appcompat:1.1.0-beta01' 32 | implementation 'androidx.core:core-ktx:1.2.0-alpha02' 33 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 34 | implementation 'androidx.recyclerview:recyclerview:1.0.0' 35 | 36 | 37 | //Firebase 38 | implementation "com.google.firebase:firebase-core:$firebase_core_version" 39 | implementation "com.google.firebase:firebase-firestore:$firebase_firestore_version" 40 | 41 | //GeoFirestore library 42 | implementation project(':geofirestore') 43 | 44 | //Test API 45 | testImplementation 'junit:junit:4.12' 46 | androidTestImplementation 'androidx.test:runner:1.2.0' 47 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 48 | } 49 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "384239095893", 4 | "firebase_url": "https://geofirestoreexample-31e4a.firebaseio.com", 5 | "project_id": "geofirestoreexample-31e4a", 6 | "storage_bucket": "geofirestoreexample-31e4a.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:384239095893:android:cc914ae167f6bbe8", 12 | "android_client_info": { 13 | "package_name": "com.supercaly.geofirestore" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "384239095893-gg7mu89bsk3ul0pi6ad19ocodbm433vh.apps.googleusercontent.com", 19 | "client_type": 1, 20 | "android_info": { 21 | "package_name": "com.supercaly.geofirestore", 22 | "certificate_hash": "ebbf34d44976d4478565823ba692b62f73ad184f" 23 | } 24 | }, 25 | { 26 | "client_id": "384239095893-cvfdvbsmrt58vdg582bsdjq3a2vqgj62.apps.googleusercontent.com", 27 | "client_type": 3 28 | } 29 | ], 30 | "api_key": [ 31 | { 32 | "current_key": "AIzaSyBNpFP4phqAt_p-SD_BhThWq8nzyd0v2Qc" 33 | } 34 | ], 35 | "services": { 36 | "appinvite_service": { 37 | "other_platform_oauth_client": [ 38 | { 39 | "client_id": "384239095893-cvfdvbsmrt58vdg582bsdjq3a2vqgj62.apps.googleusercontent.com", 40 | "client_type": 3 41 | } 42 | ] 43 | } 44 | } 45 | }, 46 | { 47 | "client_info": { 48 | "mobilesdk_app_id": "1:384239095893:android:b7aa137d77149e12", 49 | "android_client_info": { 50 | "package_name": "org.imperiumlabs.geofirestoreexample" 51 | } 52 | }, 53 | "oauth_client": [ 54 | { 55 | "client_id": "384239095893-9e1phoj9bhaklrlu7k643i04c8tjnjo3.apps.googleusercontent.com", 56 | "client_type": 1, 57 | "android_info": { 58 | "package_name": "org.imperiumlabs.geofirestoreexample", 59 | "certificate_hash": "ebbf34d44976d4478565823ba692b62f73ad184f" 60 | } 61 | }, 62 | { 63 | "client_id": "384239095893-cvfdvbsmrt58vdg582bsdjq3a2vqgj62.apps.googleusercontent.com", 64 | "client_type": 3 65 | } 66 | ], 67 | "api_key": [ 68 | { 69 | "current_key": "AIzaSyBNpFP4phqAt_p-SD_BhThWq8nzyd0v2Qc" 70 | } 71 | ], 72 | "services": { 73 | "appinvite_service": { 74 | "other_platform_oauth_client": [ 75 | { 76 | "client_id": "384239095893-cvfdvbsmrt58vdg582bsdjq3a2vqgj62.apps.googleusercontent.com", 77 | "client_type": 3 78 | } 79 | ] 80 | } 81 | } 82 | } 83 | ], 84 | "configuration_version": "1" 85 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/imperiumlabs/geofirestoreexample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestoreexample; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("org.imperiumlabs.geofirestoreexample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/imperiumlabs/geofirestoreexample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestoreexample 2 | 3 | import android.os.Bundle 4 | import android.util.Log 5 | import android.widget.ArrayAdapter 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.google.firebase.firestore.DocumentSnapshot 8 | import com.google.firebase.firestore.FirebaseFirestore 9 | import com.google.firebase.firestore.GeoPoint 10 | import kotlinx.android.synthetic.main.activity_main.* 11 | import org.imperiumlabs.geofirestore.GeoFirestore 12 | import org.imperiumlabs.geofirestore.listeners.GeoQueryDataEventListener 13 | import org.imperiumlabs.geofirestore.extension.getAtLocation 14 | 15 | class MainActivity: AppCompatActivity() { 16 | 17 | companion object { 18 | private const val TAG = "MainActivity" 19 | private const val POST_COLLECTION = "POSTS" 20 | 21 | private val QUERY_CENTER = GeoPoint(37.7853889, -122.4056973) 22 | private const val QUERY_RADIUS = 5.0 23 | } 24 | 25 | private val db = FirebaseFirestore.getInstance() 26 | private val posts = db.collection(POST_COLLECTION) 27 | private val geoFirestore = GeoFirestore(posts) 28 | 29 | private val postList = arrayListOf() 30 | private lateinit var adapter: ArrayAdapter 31 | 32 | override fun onCreate(savedInstanceState: Bundle?) { 33 | super.onCreate(savedInstanceState) 34 | setContentView(R.layout.activity_main) 35 | 36 | adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, postList) 37 | post_list_view.adapter = adapter 38 | 39 | testSingleGeoQuery() 40 | } 41 | 42 | private fun testSingleGeoQuery() { 43 | geoFirestore.getAtLocation(QUERY_CENTER, QUERY_RADIUS) { p0, p1 -> 44 | if (p1 != null) { 45 | Log.e(TAG, "onError: ", p1) 46 | return@getAtLocation 47 | } else { 48 | p0?.forEach { 49 | val desc = it["DESCRIPTION"] as? String 50 | Log.i(TAG, "onSuccess: $desc") 51 | adapter.insert(desc, adapter.count) 52 | adapter.notifyDataSetChanged() 53 | } 54 | } 55 | } 56 | } 57 | 58 | private fun testGeoQuery() { 59 | val geoQuery = geoFirestore.queryAtLocation(QUERY_CENTER, QUERY_RADIUS) 60 | geoQuery.addGeoQueryDataEventListener(object : GeoQueryDataEventListener { 61 | override fun onDocumentEntered(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 62 | val desc = documentSnapshot["DESCRIPTION"] as? String 63 | Log.i(TAG, "onDocumentEntered: $desc") 64 | adapter.insert(desc, adapter.count) 65 | adapter.notifyDataSetChanged() 66 | } 67 | 68 | override fun onDocumentExited(documentSnapshot: DocumentSnapshot) { 69 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 70 | } 71 | 72 | override fun onDocumentMoved(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 73 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 74 | } 75 | 76 | override fun onDocumentChanged(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 77 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 78 | } 79 | 80 | override fun onGeoQueryReady() { 81 | Log.i(TAG, "onGeoQueryReady: ") 82 | } 83 | 84 | override fun onGeoQueryError(exception: Exception) { 85 | Log.e(TAG, "onGeoQueryError: ", exception) 86 | } 87 | }) 88 | } 89 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GeoFirestoreExample 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/org/imperiumlabs/geofirestoreexample/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestoreexample; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | //Versions of Kotlin and Firebase 6 | ext.kotlin_version = '1.3.40' 7 | ext.firebase_core_version = '17.0.0' 8 | ext.firebase_firestore_version = '20.1.0' 9 | 10 | repositories { 11 | google() 12 | jcenter() 13 | 14 | } 15 | dependencies { 16 | classpath 'com.android.tools.build:gradle:3.4.1' 17 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 18 | classpath 'com.google.gms:google-services:4.2.0' 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | google() 25 | jcenter() 26 | //Only for testing purpose 27 | maven { url 'https://jitpack.io' } 28 | } 29 | } 30 | 31 | task clean(type: Delete) { 32 | delete rootProject.buildDir 33 | } 34 | -------------------------------------------------------------------------------- /docs/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Deprecated List 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Deprecated API

73 |

Contents

74 |
75 | 76 |
77 | 78 | 79 | 80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /docs/index-files/index-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | A-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

A

75 |
76 |
addGeoQueryDataEventListener(GeoQueryDataEventListener) - Method in class org.imperiumlabs.geofirestore.GeoQuery
77 |
78 |
Adds a new GeoQueryEventListener to this GeoQuery.
79 |
80 |
addGeoQueryEventListener(GeoQueryEventListener) - Method in class org.imperiumlabs.geofirestore.GeoQuery
81 |
82 |
Adds a new GeoQueryEventListener to this GeoQuery.
83 |
84 |
addition_isCorrect() - Method in class org.imperiumlabs.geofirestore.ExampleUnitTest
85 |
 
86 |
87 | A B C D E G H I J L M O Q R S T U V W 
88 | 89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 | 105 |
106 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs/index-files/index-10.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | L-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

L

75 |
76 |
latitude - Variable in class org.imperiumlabs.geofirestore.GeoLocation
77 |
78 |
The latitude of this location in the range of [-90, 90]
79 |
80 |
LOGGER - Static variable in class org.imperiumlabs.geofirestore.GeoFirestore
81 |
 
82 |
longitude - Variable in class org.imperiumlabs.geofirestore.GeoLocation
83 |
84 |
The longitude of this location in the range of [-180, 180]
85 |
86 |
87 | A B C D E G H I J L M O Q R S T U V W 
88 | 89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 | 105 |
106 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs/index-files/index-11.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | M-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

M

75 |
76 |
MAX_PRECISION - Static variable in class org.imperiumlabs.geofirestore.core.GeoHash
77 |
 
78 |
MAX_PRECISION_BITS - Static variable in class org.imperiumlabs.geofirestore.core.GeoHash
79 |
 
80 |
METERS_PER_DEGREE_LATITUDE - Static variable in class org.imperiumlabs.geofirestore.util.Constants
81 |
 
82 |
83 | A B C D E G H I J L M O Q R S T U V W 
84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 101 |
102 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/index-files/index-13.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Q-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

Q

75 |
76 |
queriesAtLocation(GeoLocation, double) - Static method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
77 |
 
78 |
queryAtLocation(GeoPoint, double) - Method in class org.imperiumlabs.geofirestore.GeoFirestore
79 |
80 |
Returns a new Query object centered at the given location and with the given radius.
81 |
82 |
queryForGeoHash(GeoHash, int) - Static method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
83 |
 
84 |
85 | A B C D E G H I J L M O Q R S T U V W 
86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 103 |
104 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/index-files/index-15.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | S-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

S

75 |
76 |
setCenter(GeoPoint) - Method in class org.imperiumlabs.geofirestore.GeoQuery
77 |
78 |
Sets the new center of this query and triggers new events if necessary.
79 |
80 |
setLocation(String, GeoPoint) - Method in class org.imperiumlabs.geofirestore.GeoFirestore
81 |
82 |
Sets the location of a document.
83 |
84 |
setLocation(String, GeoPoint, GeoFirestore.CompletionListener) - Method in class org.imperiumlabs.geofirestore.GeoFirestore
85 |
86 |
Sets the location of a document.
87 |
88 |
setLocation(GeoPoint, double) - Method in class org.imperiumlabs.geofirestore.GeoQuery
89 |
90 |
Sets the center and radius (in kilometers) of this query, and triggers new events if necessary.
91 |
92 |
setRadius(double) - Method in class org.imperiumlabs.geofirestore.GeoQuery
93 |
94 |
Sets the radius of this query, in kilometers, and triggers new events if necessary.
95 |
96 |
97 | A B C D E G H I J L M O Q R S T U V W 
98 | 99 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | 115 |
116 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /docs/index-files/index-16.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | T-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

T

75 |
76 |
toString() - Method in class org.imperiumlabs.geofirestore.core.GeoHash
77 |
 
78 |
toString() - Method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
79 |
 
80 |
toString() - Method in class org.imperiumlabs.geofirestore.GeoLocation
81 |
 
82 |
83 | A B C D E G H I J L M O Q R S T U V W 
84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 101 |
102 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/index-files/index-17.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | U-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

U

75 |
76 |
useAppContext() - Method in class org.imperiumlabs.geofirestore.ExampleInstrumentedTest
77 |
 
78 |
79 | A B C D E G H I J L M O Q R S T U V W 
80 | 81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/index-files/index-18.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | V-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

V

75 |
76 |
valueToBase32Char(int) - Static method in class org.imperiumlabs.geofirestore.util.Base32Utils
77 |
 
78 |
79 | A B C D E G H I J L M O Q R S T U V W 
80 | 81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/index-files/index-19.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | W-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

W

75 |
76 |
wrapLongitude(double) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
77 |
 
78 |
79 | A B C D E G H I J L M O Q R S T U V W 
80 | 81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/index-files/index-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | B-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

B

75 |
76 |
base32CharToValue(char) - Static method in class org.imperiumlabs.geofirestore.util.Base32Utils
77 |
 
78 |
Base32Utils - Class in org.imperiumlabs.geofirestore.util
79 |
 
80 |
BITS_PER_BASE32_CHAR - Static variable in class org.imperiumlabs.geofirestore.util.Base32Utils
81 |
 
82 |
bitsForBoundingBox(GeoLocation, double) - Static method in class org.imperiumlabs.geofirestore.core.GeoHashQuery.Utils
83 |
 
84 |
bitsLatitude(double) - Static method in class org.imperiumlabs.geofirestore.core.GeoHashQuery.Utils
85 |
 
86 |
bitsLongitude(double, double) - Static method in class org.imperiumlabs.geofirestore.core.GeoHashQuery.Utils
87 |
 
88 |
89 | A B C D E G H I J L M O Q R S T U V W 
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 107 |
108 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/index-files/index-3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | C-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

C

75 |
76 |
canJoinWith(GeoHashQuery) - Method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
77 |
 
78 |
capRadius(double) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
79 |
 
80 |
Constants - Class in org.imperiumlabs.geofirestore.util
81 |
 
82 |
containsGeoHash(GeoHash) - Method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
83 |
 
84 |
coordinatesValid(double, double) - Static method in class org.imperiumlabs.geofirestore.GeoLocation
85 |
86 |
Checks if these coordinates are valid geo coordinates.
87 |
88 |
89 | A B C D E G H I J L M O Q R S T U V W 
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 107 |
108 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/index-files/index-4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | D-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

D

75 |
76 |
distance(GeoLocation, GeoLocation) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
77 |
 
78 |
distance(double, double, double, double) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
79 |
 
80 |
distanceToLatitudeDegrees(double) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
81 |
 
82 |
distanceToLongitudeDegrees(double, double) - Static method in class org.imperiumlabs.geofirestore.util.GeoUtils
83 |
 
84 |
85 | A B C D E G H I J L M O Q R S T U V W 
86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 103 |
104 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/index-files/index-7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | H-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

H

75 |
76 |
hashCode() - Method in class org.imperiumlabs.geofirestore.core.GeoHash
77 |
 
78 |
hashCode() - Method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
79 |
 
80 |
hashCode() - Method in class org.imperiumlabs.geofirestore.GeoLocation
81 |
 
82 |
83 | A B C D E G H I J L M O Q R S T U V W 
84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 101 |
102 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/index-files/index-8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | I-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

I

75 |
76 |
isValidBase32String(String) - Static method in class org.imperiumlabs.geofirestore.util.Base32Utils
77 |
 
78 |
79 | A B C D E G H I J L M O Q R S T U V W 
80 | 81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/index-files/index-9.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | J-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
A B C D E G H I J L M O Q R S T U V W  72 | 73 | 74 |

J

75 |
76 |
joinWith(GeoHashQuery) - Method in class org.imperiumlabs.geofirestore.core.GeoHashQuery
77 |
 
78 |
79 | A B C D E G H I J L M O Q R S T U V W 
80 | 81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Generated Documentation (Untitled) 7 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <noscript> 69 | <div>JavaScript is disabled on your browser.</div> 70 | </noscript> 71 | <h2>Frame Alert</h2> 72 | <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="overview-summary.html">Non-frame version</a>.</p> 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/core/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.core 7 | 8 | 9 | 10 | 11 | 12 |

org.imperiumlabs.geofirestore.core

13 |
14 |

Classes

15 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/core/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.core 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Package org.imperiumlabs.geofirestore.core

73 |
74 |
75 |
    76 |
  • 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
    Class Summary 
    ClassDescription
    GeoHash 
    GeoHashQuery 
    GeoHashQuery.Utils 
    98 |
  • 99 |
100 |
101 | 102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 118 |
119 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/core/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.core Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Hierarchy For Package org.imperiumlabs.geofirestore.core

73 | Package Hierarchies: 74 | 77 |
78 |
79 |

Class Hierarchy

80 |
    81 |
  • java.lang.Object 82 | 87 |
  • 88 |
89 |
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 107 |
108 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore 7 | 8 | 9 | 10 | 11 | 12 |

org.imperiumlabs.geofirestore

13 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Hierarchy For Package org.imperiumlabs.geofirestore

73 | Package Hierarchies: 74 | 77 |
78 |
79 |

Class Hierarchy

80 | 91 |

Interface Hierarchy

92 | 98 |
99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 116 |
117 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/util/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.util 7 | 8 | 9 | 10 | 11 | 12 |

org.imperiumlabs.geofirestore.util

13 |
14 |

Classes

15 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/util/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.util 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Package org.imperiumlabs.geofirestore.util

73 |
74 |
75 |
    76 |
  • 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
    Class Summary 
    ClassDescription
    Base32Utils 
    Constants 
    GeoUtils 
    98 |
  • 99 |
100 |
101 | 102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 118 |
119 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/org/imperiumlabs/geofirestore/util/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | org.imperiumlabs.geofirestore.util Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Hierarchy For Package org.imperiumlabs.geofirestore.util

73 | Package Hierarchies: 74 | 77 |
78 |
79 |

Class Hierarchy

80 |
    81 |
  • java.lang.Object 82 |
      83 |
    • org.imperiumlabs.geofirestore.util.Base32Utils
    • 84 |
    • org.imperiumlabs.geofirestore.util.Constants
    • 85 |
    • org.imperiumlabs.geofirestore.util.GeoUtils
    • 86 |
    87 |
  • 88 |
89 |
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 107 |
108 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/overview-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Overview List 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 |

 

22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/overview-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Overview 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
Packages 
PackageDescription
org.imperiumlabs.geofirestore 
org.imperiumlabs.geofirestore.core 
org.imperiumlabs.geofirestore.util 
93 |
94 | 95 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 111 |
112 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /docs/package-list: -------------------------------------------------------------------------------- 1 | org.imperiumlabs.geofirestore 2 | org.imperiumlabs.geofirestore.core 3 | org.imperiumlabs.geofirestore.util 4 | -------------------------------------------------------------------------------- /docs/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /geofirestore/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /geofirestore/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 28 7 | 8 | defaultConfig { 9 | minSdkVersion 15 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | } 15 | 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(dir: 'libs', include: ['*.jar']) 26 | 27 | //Kotlin 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 29 | 30 | //Firebase 31 | implementation "com.google.firebase:firebase-core:$firebase_core_version" 32 | implementation "com.google.firebase:firebase-firestore:$firebase_firestore_version" 33 | 34 | //Test Implementations 35 | testImplementation 'junit:junit:4.12' 36 | testImplementation 'org.mockito:mockito-core:2.19.0' 37 | androidTestImplementation 'androidx.test:runner:1.2.0' 38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 39 | } 40 | -------------------------------------------------------------------------------- /geofirestore/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /geofirestore/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /geofirestore/src/androidTest/java/org/imperiumlabs/geofirestore/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("org.imperiumlabs.geofirestore.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /geofirestore/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/AndroidEventRaiser.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | 6 | // FULLY TESTED 7 | 8 | class AndroidEventRaiser: EventRaiser { 9 | private val mainThreadHandler = Handler(Looper.getMainLooper()) 10 | 11 | override fun raiseEvent(r: Runnable) { 12 | this.mainThreadHandler.post(r) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/EventRaiser.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore 2 | 3 | // FULLY TESTED 4 | 5 | interface EventRaiser { 6 | fun raiseEvent(r: Runnable) 7 | } 8 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/GeoLocation.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore 2 | 3 | // FULLY TESTED 4 | 5 | /** 6 | * A wrapper class for location coordinates. 7 | */ 8 | class GeoLocation( 9 | // The latitude of this location in the range of [-90, 90] 10 | val latitude: Double, 11 | // The longitude of this location in the range of [-180, 180] 12 | val longitude: Double) { 13 | 14 | companion object { 15 | /** 16 | * Checks if these coordinates are valid geo coordinates. 17 | * @param latitude The latitude must be in the range [-90, 90] 18 | * @param longitude The longitude must be in the range [-180, 180] 19 | * @return True if these are valid geo coordinates 20 | */ 21 | fun coordinatesValid(latitude: Double, longitude: Double) = 22 | latitude >= -90 && 23 | latitude <= 90 && 24 | longitude >= -180 && 25 | longitude <= 180 26 | } 27 | 28 | /** 29 | * Creates a new GeoLocation with the given latitude and longitude. 30 | * 31 | * @throws IllegalArgumentException If the coordinates are not valid geo coordinates 32 | */ 33 | init { 34 | if (!coordinatesValid(latitude, longitude)) 35 | throw IllegalArgumentException("Not a valid geo location: $latitude, $longitude") 36 | } 37 | 38 | 39 | override fun toString() = "GeoLocation($latitude, $longitude)" 40 | 41 | override fun equals(other: Any?): Boolean { 42 | if (other == null || other !is GeoLocation) 43 | return false 44 | if (other.latitude.compareTo(this.latitude) != 0) return false 45 | if (other.longitude.compareTo(this.longitude) != 0) return false 46 | 47 | return true 48 | } 49 | 50 | override fun hashCode(): Int { 51 | var result: Int 52 | var temp = this.latitude.toLong() 53 | result = (temp xor (temp ushr 32)).toInt() 54 | temp = this.longitude.toLong() 55 | result = 31*result+(temp xor (temp ushr 32)).toInt() 56 | return result 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/ThreadEventRaiser.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore 2 | 3 | import java.util.concurrent.Executors 4 | 5 | // FULLY TESTED 6 | 7 | class ThreadEventRaiser: EventRaiser { 8 | 9 | private val executorService = Executors.newSingleThreadExecutor() 10 | 11 | override fun raiseEvent(r: Runnable) { 12 | this.executorService.submit(r) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/core/GeoHash.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.core 2 | 3 | import org.imperiumlabs.geofirestore.util.Base32Utils 4 | import org.imperiumlabs.geofirestore.util.Base32Utils.BITS 5 | import org.imperiumlabs.geofirestore.GeoLocation 6 | import java.util.Locale.US 7 | 8 | // TODO: 05/05/19 Test if makeGeoHash() work correctly 9 | 10 | /** 11 | * A GeoHash instance is used to generate and store geohash strings 12 | */ 13 | class GeoHash { 14 | 15 | //The GeoHash String value 16 | var geoHashString: String 17 | private set 18 | 19 | companion object { 20 | // The default precision of a geohash 21 | private const val DEFAULT_PRECISION = 10 22 | 23 | // The maximal precision of a geohash 24 | const val MAX_PRECISION = 22 25 | 26 | // The maximal number of bits precision for a geohash 27 | const val MAX_PRECISION_BITS = MAX_PRECISION * Base32Utils.BITS_PER_BASE32_CHAR 28 | 29 | } 30 | 31 | //Constructor with latitude, longitude and DEFAULT_PRECISION 32 | constructor(latitude: Double, longitude: Double): this(latitude, longitude, DEFAULT_PRECISION) 33 | 34 | //Constructor with GeoLocation and DEFAULT_PRECISION 35 | constructor(location: GeoLocation): this(location.latitude, location.longitude, DEFAULT_PRECISION) 36 | 37 | //Constructor with GeoLocation and precision 38 | constructor(location: GeoLocation, precision: Int): this(location.latitude, location.longitude, precision) 39 | 40 | //Constructor with latitude, longitude and precision 41 | constructor(latitude: Double, longitude: Double, precision: Int) { 42 | if (precision < 1) 43 | throw IllegalArgumentException("Precision of GeoHash must be larger than zero!") 44 | 45 | if (precision > MAX_PRECISION) 46 | throw IllegalArgumentException("Precision of a GeoHash must be less than " + (MAX_PRECISION + 1) + "!") 47 | 48 | if (!GeoLocation.coordinatesValid(latitude, longitude)) 49 | throw IllegalArgumentException(String.format(US, "Not valid location coordinates: [%f, %f]", latitude, longitude)) 50 | 51 | //The supplied data are valid... start creating the geo hash 52 | this.geoHashString = makeGeoHash(latitude, longitude, precision) 53 | } 54 | 55 | //Constructor with hash string 56 | constructor(hash: String) { 57 | if (!Base32Utils.isValidBase32String(hash)) 58 | throw IllegalArgumentException("Not a valid geoHashString: $hash") 59 | this.geoHashString = hash 60 | } 61 | 62 | /* 63 | * Make the geohash string from supplied latitude, longitude, precision 64 | */ 65 | private fun makeGeoHash(latitude: Double, longitude: Double, precision: Int): String { 66 | val lat = arrayOf(-90.0, 90.0) 67 | val lon = arrayOf(-180.0, 180.0) 68 | val buffer = CharArray(precision) 69 | 70 | //Calculate the value for every letter until we obtain a word of length precision 71 | for (i in 0 until precision) { 72 | var value = 0 73 | //Cycle every bit from 0 to BITS_PER_BASE32_CHAR (4) 74 | for (j in 0 until Base32Utils.BITS_PER_BASE32_CHAR) { 75 | val evenBit = (((i* Base32Utils.BITS_PER_BASE32_CHAR) + j) % 2) == 0 76 | if (evenBit) { 77 | //If it's in an even position we calculate the value based on the longitude 78 | val mid = (lon[0] + lon[1]) / 2 79 | if (longitude > mid) { 80 | value = value or BITS[j] 81 | lon[0] = mid 82 | } else 83 | lon[1] = mid 84 | } else { 85 | //If it's in an odd position we calculate the value based on the latitude 86 | val mid = (lat[0] + lat[1]) / 2 87 | if (latitude > mid) { 88 | value = value or BITS[j] 89 | lat[0] = mid 90 | } else 91 | lat[1] = mid 92 | } 93 | } 94 | buffer[i] = Base32Utils.valueToBase32Char(value) 95 | } 96 | return String(buffer) 97 | } 98 | 99 | override fun equals(other: Any?): Boolean { 100 | if (other == null || other !is GeoHash) return false 101 | return geoHashString == other.geoHashString 102 | } 103 | 104 | override fun toString() = "GeoHash(geoHashString='$geoHashString')" 105 | 106 | override fun hashCode() = this.geoHashString.hashCode() 107 | } -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/extension/CollectionExtension.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.extension 2 | 3 | /** 4 | * Map every object of T in an Iterable to a MutableCollection of R 5 | * excluding the non null's elements 6 | * 7 | * example: 8 | * list = listOf(listOf(1, 2, null), listOf(3, 4, 5)) 9 | * list2 = arrayListOf() 10 | * list.mapNotNullManyTo(list2) {it} 11 | * 12 | * before: 13 | * -list [[1,2,null],[3,4,5]] 14 | * -list2 [] 15 | * after: 16 | * -list [[1,2,null],[3,4,5]] 17 | * -list2 [1,2,3,4,5] 18 | */ 19 | inline fun> Iterable.mapNotNullManyTo(destination: C, transform: (T)->Collection?): C { 20 | forEach { element -> 21 | transform(element)?.let { collection -> 22 | val c = arrayListOf() 23 | collection.forEach { r -> r?.let { c.add(it) } } 24 | destination.addAll(c) 25 | } 26 | } 27 | return destination 28 | } -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/extension/GeoFirestoreExt.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.extension 2 | 3 | import com.google.firebase.firestore.DocumentSnapshot 4 | import com.google.firebase.firestore.GeoPoint 5 | import org.imperiumlabs.geofirestore.GeoFirestore 6 | 7 | /* 8 | * This file contains a series of extension functions 9 | * used to differentiate the Kotlin lambda version of 10 | * the same functions in the GeoFirestore class 11 | */ 12 | 13 | /** 14 | * Gets the current location for a document and calls the callback with the current value. 15 | * 16 | * @param documentID The documentID of the document whose location to get 17 | * @param callback The Lambda function that is called once the location is retrieved 18 | */ 19 | fun GeoFirestore.getLocation(documentID: String, callback: (location: GeoPoint?, exception: Exception?)->Unit) { 20 | this.getLocation(documentID, object : GeoFirestore.LocationCallback { 21 | override fun onComplete(location: GeoPoint?, exception: Exception?) { 22 | callback(location, exception) 23 | } 24 | }) 25 | } 26 | 27 | /** 28 | * Removes the location of a document from this GeoFirestore. 29 | * 30 | * @param documentID The documentID of the document to remove from this GeoFirestore 31 | * @param completionListener A lambda function that is called once the location is successfully removed 32 | * from the server or an error occurred 33 | */ 34 | fun GeoFirestore.removeLocation(documentID: String?, completionListener: (exception: Exception?)->Unit) { 35 | this.removeLocation(documentID, object : GeoFirestore.CompletionCallback { 36 | override fun onComplete(exception: Exception?) { 37 | completionListener(exception) 38 | } 39 | }) 40 | } 41 | 42 | /** 43 | * Sets the location of a document. 44 | * 45 | * @param documentID The documentID of the document to save the location for 46 | * @param location The location of this document 47 | * @param completionListener Lambda function called when the location was successfully saved on the server 48 | * or an error occurred 49 | */ 50 | fun GeoFirestore.setLocation(documentID: String?, location: GeoPoint, completionListener: (exception: Exception?)->Unit) { 51 | this.setLocation(documentID, location, object : GeoFirestore.CompletionCallback { 52 | override fun onComplete(exception: Exception?) { 53 | completionListener(exception) 54 | } 55 | }) 56 | } 57 | 58 | /** 59 | * Returns a new SingleGeoQuery object centered at a given location and with the given radius. 60 | * 61 | * @param center The center of the query 62 | * @param radius The radius of the query, in kilometers. The maximum radius that is 63 | * supported is about 8587km. If a radius bigger than this is passed we'll cap it. 64 | * @return The new SingleGeoQuery object 65 | */ 66 | fun GeoFirestore.getAtLocation(center: GeoPoint, radius: Double, callback: (p0: List?, p1: Exception?)->Unit) { 67 | this.getAtLocation(center, radius, object : GeoFirestore.SingleGeoQueryDataEventCallback { 68 | override fun onComplete(documentSnapshots: List?, exception: Exception?) { 69 | callback(documentSnapshots, exception) 70 | } 71 | }) 72 | } -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/listeners/EventListenerBridge.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.listeners 2 | 3 | import com.google.firebase.firestore.DocumentSnapshot 4 | import com.google.firebase.firestore.GeoPoint 5 | 6 | // FULLY TESTED 7 | 8 | /** 9 | * GeoQuery notifies listeners with this interface about documents that entered, exited, or moved within the query. 10 | */ 11 | class EventListenerBridge(private val listener: GeoQueryEventListener): GeoQueryDataEventListener { 12 | 13 | override fun onDocumentEntered(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 14 | listener.onKeyEntered(documentSnapshot.id, location) 15 | } 16 | 17 | override fun onDocumentExited(documentSnapshot: DocumentSnapshot) { 18 | listener.onKeyExited(documentSnapshot.id) 19 | } 20 | 21 | override fun onDocumentMoved(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 22 | listener.onKeyMoved(documentSnapshot.id, location) 23 | } 24 | 25 | override fun onDocumentChanged(documentSnapshot: DocumentSnapshot, location: GeoPoint) { 26 | //No-op 27 | } 28 | 29 | override fun onGeoQueryReady() { 30 | listener.onGeoQueryReady() 31 | } 32 | 33 | override fun onGeoQueryError(exception: Exception) { 34 | listener.onGeoQueryError(exception) 35 | } 36 | 37 | 38 | override fun equals(other: Any?): Boolean { 39 | if (other == null || other !is EventListenerBridge) 40 | return false 41 | return listener == other.listener 42 | } 43 | 44 | override fun hashCode(): Int { 45 | return listener.hashCode() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/listeners/GeoQueryDataEventListener.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.listeners 2 | 3 | import com.google.firebase.firestore.DocumentSnapshot 4 | import com.google.firebase.firestore.GeoPoint 5 | 6 | // FULLY TESTED 7 | 8 | /** 9 | * GeoQuery notifies listeners with this interface about documents that entered, exited, or moved within the query. 10 | */ 11 | interface GeoQueryDataEventListener { 12 | 13 | /** 14 | * Called if a document entered the search area of the GeoQuery. This method is called for every document currently in the 15 | * search area at the time of adding the listener. 16 | * 17 | * This method is once per document, and is only called again if onDocumentExited was called in the meantime. 18 | * 19 | * @param documentSnapshot The snapshot of the associated document that entered the search area 20 | * @param location The location for this document 21 | */ 22 | fun onDocumentEntered(documentSnapshot: DocumentSnapshot, location: GeoPoint) 23 | 24 | /** 25 | * Called if a document exited the search area of the GeoQuery. This is method is only called if onDocumentEntered was called 26 | * for the document. 27 | * 28 | * @param documentSnapshot The snapshot of the associated document that exited the search area 29 | */ 30 | fun onDocumentExited(documentSnapshot: DocumentSnapshot) 31 | 32 | /** 33 | * Called if a document moved within the search area. 34 | * 35 | * This method can be called multiple times. 36 | * 37 | * @param documentSnapshot The snapshot of the associated document that moved within the search area 38 | * @param location The location for this document 39 | */ 40 | fun onDocumentMoved(documentSnapshot: DocumentSnapshot, location: GeoPoint) 41 | 42 | /** 43 | * Called if a document changed within the search area. 44 | * 45 | * An onDocumentMoved() is always followed by onDocumentChanged() but it is be possible to see 46 | * onDocumentChanged() without an preceding onDocumentMoved(). 47 | * 48 | * This method can be called multiple times for a single location change, due to the way 49 | * Firestore handles floating point numbers. 50 | * 51 | * 52 | * @param documentSnapshot The snapshot of the associated document that moved within the search area 53 | * @param location The location for this document 54 | */ 55 | fun onDocumentChanged(documentSnapshot: DocumentSnapshot, location: GeoPoint) 56 | 57 | /** 58 | * Called once all initial GeoFirestore data has been loaded and the relevant events have been fired for this query. 59 | * Every time the query criteria is updated, this observer will be called after the updated query has fired the 60 | * appropriate document entered or document exited events. 61 | */ 62 | fun onGeoQueryReady() 63 | 64 | /** 65 | * Called in case an exception occurred while retrieving locations for a query, e.g. violating security rules. 66 | * @param exception The exception that occurred while retrieving the query 67 | */ 68 | fun onGeoQueryError(exception: Exception) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/listeners/GeoQueryEventListener.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.listeners 2 | 3 | import com.google.firebase.firestore.GeoPoint 4 | 5 | // FULLY TESTED 6 | 7 | /** 8 | * GeoQuery notifies listeners with this interface about documentIDs that entered, exited, or moved within the query. 9 | */ 10 | interface GeoQueryEventListener { 11 | 12 | /** 13 | * Called if a documentID entered the search area of the GeoQuery. This method is called for every documentID currently in the 14 | * search area at the time of adding the listener. 15 | * 16 | * This method is once per documentID, and is only called again if onKeyExited was called in the meantime. 17 | * 18 | * @param documentID The documentID that entered the search area 19 | * @param location The location for this documentID 20 | */ 21 | fun onKeyEntered(documentID: String, location: GeoPoint) 22 | 23 | /** 24 | * Called if a documentID exited the search area of the GeoQuery. This method is only called if onKeyEntered was called 25 | * for the documentID. 26 | * 27 | * @param documentID The documentID that exited the search area 28 | */ 29 | fun onKeyExited(documentID: String) 30 | 31 | /** 32 | * Called if a documentID moved within the search area. 33 | * 34 | * This method can be called multiple times. 35 | * 36 | * @param documentID The documentID that moved within the search area 37 | * @param location The location for this documentID 38 | */ 39 | fun onKeyMoved(documentID: String, location: GeoPoint) 40 | 41 | /** 42 | * Called once all initial GeoFirestore data has been loaded and the relevant events have been fired for this query. 43 | * Every time the query criteria is updated, this observer will be called after the updated query has fired the 44 | * appropriate key entered or key exited events. 45 | */ 46 | fun onGeoQueryReady() 47 | 48 | /** 49 | * Called in case an exception occurred while retrieving locations for a query, e.g. violating security rules. 50 | * @param exception The exception that occurred while retrieving the query 51 | */ 52 | fun onGeoQueryError(exception: Exception) 53 | 54 | } 55 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/util/Base32Utils.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.util 2 | 3 | 4 | // FULLY TESTED 5 | object Base32Utils { 6 | 7 | //number of bits per base 32 character 8 | const val BITS_PER_BASE32_CHAR = 5 9 | 10 | val BITS = arrayOf(16, 8, 4, 2, 1) 11 | 12 | //String representing the Base32 character map 13 | private const val BASE32_CHARS = "0123456789bcdefghjkmnpqrstuvwxyz" 14 | 15 | /* 16 | * This method convert a given value to his corresponding Base32 character 17 | */ 18 | fun valueToBase32Char(value: Int): Char { 19 | if (value < 0 || value >= BASE32_CHARS.length) 20 | throw IllegalArgumentException("Not a valid base32 value: $value") 21 | return BASE32_CHARS[value] 22 | } 23 | 24 | /* 25 | * This method convert a given Base32 character to his corresponding value 26 | */ 27 | fun base32CharToValue(base32Char: Char): Int { 28 | val value = BASE32_CHARS.indexOf(base32Char) 29 | if (value == -1) 30 | throw IllegalArgumentException("Not a valid base32 char: $base32Char") 31 | return value 32 | } 33 | 34 | /* 35 | * This method check if a given geo hash is valid 36 | */ 37 | fun isValidBase32String(string: String) = 38 | if (string.isNotEmpty()) 39 | string.matches("^[$BASE32_CHARS]*$".toRegex()) 40 | else false 41 | } 42 | -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/util/Constants.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.util 2 | 3 | // FULLY TESTED 4 | 5 | object Constants { 6 | 7 | // Length of a degree latitude at the equator 8 | const val METERS_PER_DEGREE_LATITUDE: Double = 110574.0 9 | 10 | // The equatorial circumference of the earth in meters 11 | const val EARTH_MERIDIONAL_CIRCUMFERENCE: Double = 40007860.0 12 | 13 | // The equatorial radius of the earth in meters 14 | const val EARTH_EQ_RADIUS: Double = 6378137.0 15 | 16 | // The meridional radius of the earth in meters 17 | const val EARTH_POLAR_RADIUS: Double = 6357852.3 18 | 19 | /* The following value assumes a polar radius of 20 | * r_p = 6356752.3 21 | * and an equatorial radius of 22 | * r_e = 6378137 23 | * The value is calculated as e2 == (r_e^2 - r_p^2)/(r_e^2) 24 | * Use exact value to avoid rounding errors 25 | */ 26 | const val EARTH_E2: Double = 0.00669447819799 27 | 28 | // Cutoff for floating point calculations 29 | const val EPSILON: Double = 1e-12 30 | } -------------------------------------------------------------------------------- /geofirestore/src/main/java/org/imperiumlabs/geofirestore/util/GeoUtils.kt: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore.util 2 | 3 | import org.imperiumlabs.geofirestore.GeoFirestore 4 | import org.imperiumlabs.geofirestore.GeoLocation 5 | 6 | // FULLY TESTED 7 | 8 | object GeoUtils { 9 | 10 | private const val MAX_SUPPORTED_RADIUS = 8587 11 | 12 | fun distance(location1: GeoLocation, location2: GeoLocation) = 13 | distance(location1.latitude, location1.longitude, location2.latitude, location2.longitude) 14 | 15 | fun distance(lat1: Double, long1: Double, lat2: Double, long2: Double): Double { 16 | // Earth's mean radius in meters 17 | val radius = (Constants.EARTH_EQ_RADIUS + Constants.EARTH_POLAR_RADIUS) / 2 18 | val latDelta = Math.toRadians(lat1 - lat2) 19 | val lonDelta = Math.toRadians(long1 - long2) 20 | 21 | val a = (Math.sin(latDelta / 2) * Math.sin(latDelta / 2)) + 22 | (Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * 23 | Math.sin(lonDelta / 2) * Math.sin(lonDelta / 2)) 24 | return radius * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) 25 | } 26 | 27 | fun distanceToLatitudeDegrees(distance: Double) = distance / Constants.METERS_PER_DEGREE_LATITUDE 28 | 29 | fun distanceToLongitudeDegrees(distance: Double, latitude: Double): Double { 30 | val radians = Math.toRadians(latitude) 31 | val numerator = Math.cos(radians) * Constants.EARTH_EQ_RADIUS * Math.PI / 180 32 | val denominator = 1 / Math.sqrt(1 - Constants.EARTH_E2 * Math.sin(radians) * Math.sin(radians)) 33 | val deltaDegrees = numerator * denominator 34 | return if (deltaDegrees < Constants.EPSILON) 35 | if (distance > 0) 360.0 else distance 36 | else 37 | Math.min(360.0, distance / deltaDegrees) 38 | } 39 | 40 | fun wrapLongitude(longitude: Double): Double { 41 | if (longitude >= -180 && longitude <= 180) 42 | return longitude 43 | val adjusted = longitude + 180 44 | return if (adjusted > 0) (adjusted % 360.0) - 180 else 180 - (-adjusted % 360) 45 | } 46 | 47 | fun capRadius(radius: Double): Double { 48 | if (radius > MAX_SUPPORTED_RADIUS) { 49 | GeoFirestore.LOGGER.warning("The radius is bigger than $MAX_SUPPORTED_RADIUS and hence we'll use that value") 50 | return MAX_SUPPORTED_RADIUS.toDouble() 51 | } 52 | return radius 53 | } 54 | } -------------------------------------------------------------------------------- /geofirestore/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GeoFirestore 3 | 4 | -------------------------------------------------------------------------------- /geofirestore/src/test/java/org/imperiumlabs/geofirestore/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.imperiumlabs.geofirestore; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | android.useAndroidX = true 15 | android.enableJetifier = true 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imperiumlabs/GeoFirestore-Android/fccb88a46ea40773ca2d360088eb915b1027b376/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 05 11:51:03 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':geofirestore' 2 | --------------------------------------------------------------------------------