├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── copyright │ ├── profiles_settings.xml │ └── utsman.xml ├── dictionaries │ └── utsman.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── utsman │ │ └── smartmarker │ │ └── sample │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── utsman │ │ │ └── smartmarker │ │ │ └── sample │ │ │ ├── MainActivity.kt │ │ │ ├── SimpleActivity.kt │ │ │ ├── TrackerMapboxActivity.kt │ │ │ └── ext.kt │ └── res │ │ ├── drawable-v24 │ │ ├── ic_launcher_foreground.xml │ │ └── ic_marker_direction_2.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_simple.xml │ │ └── activity_tracker_mapbox.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 │ └── com │ └── utsman │ └── smartmarker │ └── sample │ └── ExampleUnitTest.kt ├── base.gradle ├── build.gradle ├── buildSrc ├── build.gradle.kts ├── build │ ├── classes │ │ └── kotlin │ │ │ └── main │ │ │ ├── Core.class │ │ │ ├── DependenciesKt.class │ │ │ ├── META-INF │ │ │ └── buildSrc.kotlin_module │ │ │ ├── Maps.class │ │ │ ├── Module.class │ │ │ └── Rx.class │ ├── kotlin │ │ ├── buildSrcjar-classes.txt │ │ └── compileKotlin │ │ │ ├── build-history.bin │ │ │ ├── caches-jvm │ │ │ ├── inputs │ │ │ │ ├── source-to-output.tab │ │ │ │ ├── source-to-output.tab.keystream │ │ │ │ ├── source-to-output.tab.keystream.len │ │ │ │ ├── source-to-output.tab.len │ │ │ │ ├── source-to-output.tab.values.at │ │ │ │ ├── source-to-output.tab_i │ │ │ │ └── source-to-output.tab_i.len │ │ │ ├── jvm │ │ │ │ └── kotlin │ │ │ │ │ ├── class-fq-name-to-source.tab │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream.len │ │ │ │ │ ├── class-fq-name-to-source.tab.len │ │ │ │ │ ├── class-fq-name-to-source.tab.values.at │ │ │ │ │ ├── class-fq-name-to-source.tab_i │ │ │ │ │ ├── class-fq-name-to-source.tab_i.len │ │ │ │ │ ├── constants.tab │ │ │ │ │ ├── constants.tab.keystream │ │ │ │ │ ├── constants.tab.keystream.len │ │ │ │ │ ├── constants.tab.len │ │ │ │ │ ├── constants.tab.values.at │ │ │ │ │ ├── constants.tab_i │ │ │ │ │ ├── constants.tab_i.len │ │ │ │ │ ├── internal-name-to-source.tab │ │ │ │ │ ├── internal-name-to-source.tab.keystream │ │ │ │ │ ├── internal-name-to-source.tab.keystream.len │ │ │ │ │ ├── internal-name-to-source.tab.len │ │ │ │ │ ├── internal-name-to-source.tab.values.at │ │ │ │ │ ├── internal-name-to-source.tab_i │ │ │ │ │ ├── internal-name-to-source.tab_i.len │ │ │ │ │ ├── package-parts.tab │ │ │ │ │ ├── package-parts.tab.keystream │ │ │ │ │ ├── package-parts.tab.keystream.len │ │ │ │ │ ├── package-parts.tab.len │ │ │ │ │ ├── package-parts.tab.values.at │ │ │ │ │ ├── package-parts.tab_i │ │ │ │ │ ├── package-parts.tab_i.len │ │ │ │ │ ├── proto.tab │ │ │ │ │ ├── proto.tab.keystream │ │ │ │ │ ├── proto.tab.keystream.len │ │ │ │ │ ├── proto.tab.len │ │ │ │ │ ├── proto.tab.values.at │ │ │ │ │ ├── proto.tab_i │ │ │ │ │ ├── proto.tab_i.len │ │ │ │ │ ├── source-to-classes.tab │ │ │ │ │ ├── source-to-classes.tab.keystream │ │ │ │ │ ├── source-to-classes.tab.keystream.len │ │ │ │ │ ├── source-to-classes.tab.len │ │ │ │ │ ├── source-to-classes.tab.values.at │ │ │ │ │ ├── source-to-classes.tab_i │ │ │ │ │ └── source-to-classes.tab_i.len │ │ │ └── lookups │ │ │ │ ├── counters.tab │ │ │ │ ├── file-to-id.tab │ │ │ │ ├── file-to-id.tab.keystream │ │ │ │ ├── file-to-id.tab.keystream.len │ │ │ │ ├── file-to-id.tab.len │ │ │ │ ├── file-to-id.tab.values.at │ │ │ │ ├── file-to-id.tab_i │ │ │ │ ├── file-to-id.tab_i.len │ │ │ │ ├── id-to-file.tab │ │ │ │ ├── id-to-file.tab.keystream │ │ │ │ ├── id-to-file.tab.keystream.len │ │ │ │ ├── id-to-file.tab.len │ │ │ │ ├── id-to-file.tab.values.at │ │ │ │ ├── lookups.tab │ │ │ │ ├── lookups.tab.keystream │ │ │ │ ├── lookups.tab.keystream.len │ │ │ │ ├── lookups.tab.len │ │ │ │ ├── lookups.tab.values.at │ │ │ │ ├── lookups.tab_i │ │ │ │ └── lookups.tab_i.len │ │ │ └── last-build.bin │ ├── libs │ │ └── buildSrc.jar │ ├── pluginUnderTestMetadata │ │ └── plugin-under-test-metadata.properties │ ├── reports │ │ └── task-properties │ │ │ └── report.txt │ └── tmp │ │ └── jar │ │ └── MANIFEST.MF └── src │ └── main │ └── java │ └── Dependencies.kt ├── extensions ├── googlemaps │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── utsman │ │ │ └── smartmarker │ │ │ └── googlemaps │ │ │ └── ExampleInstrumentedTest.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── utsman │ │ │ │ └── smartmarker │ │ │ │ └── googlemaps │ │ │ │ └── Ext.kt │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── utsman │ │ └── smartmarker │ │ └── googlemaps │ │ └── ExampleUnitTest.kt ├── location │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── utsman │ │ │ └── smartmarker │ │ │ └── location │ │ │ └── ExampleInstrumentedTest.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── utsman │ │ │ │ └── smartmarker │ │ │ │ └── location │ │ │ │ ├── LocationListener.java │ │ │ │ ├── LocationUpdateListener.java │ │ │ │ └── LocationWatcher.java │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── utsman │ │ └── smartmarker │ │ └── location │ │ └── ExampleUnitTest.kt └── mapbox │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── utsman │ │ └── smartmarker │ │ └── mapbox │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── utsman │ │ │ └── smartmarker │ │ │ └── mapbox │ │ │ ├── Ext.kt │ │ │ ├── Marker.kt │ │ │ ├── MarkerBuilder.kt │ │ │ ├── MarkerOptions.kt │ │ │ └── MathUtil.kt │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── utsman │ └── smartmarker │ └── mapbox │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── smartmarker ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── utsman │ └── smartmarker │ └── ExampleInstrumentedTest.kt ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── utsman │ │ └── smartmarker │ │ ├── Ext.kt │ │ ├── MathUtil.java │ │ ├── SmartLatLon.java │ │ ├── SmartMarker.java │ │ └── SmartUtil.java └── res │ └── values │ └── strings.xml └── test └── java └── com └── utsman └── smartmarker └── ExampleUnitTest.kt /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | xmlns:android 20 | 21 | ^$ 22 | 23 | 24 | 25 |
26 |
27 | 28 | 29 | 30 | xmlns:.* 31 | 32 | ^$ 33 | 34 | 35 | BY_NAME 36 | 37 |
38 |
39 | 40 | 41 | 42 | .*:id 43 | 44 | http://schemas.android.com/apk/res/android 45 | 46 | 47 | 48 |
49 |
50 | 51 | 52 | 53 | .*:name 54 | 55 | http://schemas.android.com/apk/res/android 56 | 57 | 58 | 59 |
60 |
61 | 62 | 63 | 64 | name 65 | 66 | ^$ 67 | 68 | 69 | 70 |
71 |
72 | 73 | 74 | 75 | style 76 | 77 | ^$ 78 | 79 | 80 | 81 |
82 |
83 | 84 | 85 | 86 | .* 87 | 88 | ^$ 89 | 90 | 91 | BY_NAME 92 | 93 |
94 |
95 | 96 | 97 | 98 | .* 99 | 100 | http://schemas.android.com/apk/res/android 101 | 102 | 103 | ANDROID_ATTRIBUTE_ORDER 104 | 105 |
106 |
107 | 108 | 109 | 110 | .* 111 | 112 | .* 113 | 114 | 115 | BY_NAME 116 | 117 |
118 |
119 |
120 |
121 | 122 | 124 |
125 |
-------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/copyright/utsman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/dictionaries/utsman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | googlemaps 5 | mapbox 6 | smartmarker 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Muhammad Utsman 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'com.android.application' 18 | 19 | apply plugin: 'kotlin-android' 20 | 21 | apply plugin: 'kotlin-android-extensions' 22 | 23 | android { 24 | compileSdkVersion 29 25 | buildToolsVersion "29.0.2" 26 | defaultConfig { 27 | applicationId "com.utsman.smartmarker.sample" 28 | minSdkVersion 16 29 | targetSdkVersion 29 30 | versionCode 1 31 | versionName "1.0" 32 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 33 | } 34 | buildTypes { 35 | release { 36 | minifyEnabled false 37 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 38 | } 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation Core.kotlin 44 | implementation Core.appCompat 45 | implementation Core.ktx 46 | 47 | implementation Maps.googleMap 48 | implementation Maps.mapbox 49 | 50 | implementation Maps.rxLocation 51 | implementation Maps.gmsLocationService 52 | 53 | implementation Rx.rxJava 54 | implementation Rx.rxAndroid 55 | 56 | implementation project(Module.smartMarker) 57 | implementation project(":extensions:googlemaps") 58 | implementation project(":extensions:mapbox") 59 | implementation project(":extensions:location") 60 | 61 | implementation 'com.karumi:dexter:6.0.0' 62 | 63 | } 64 | -------------------------------------------------------------------------------- /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/com/utsman/smartmarker/sample/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.utsman.smartmarker.sample 18 | 19 | import androidx.test.platform.app.InstrumentationRegistry 20 | import androidx.test.ext.junit.runners.AndroidJUnit4 21 | 22 | import org.junit.Test 23 | import org.junit.runner.RunWith 24 | 25 | import org.junit.Assert.* 26 | 27 | /** 28 | * Instrumented test, which will execute on an Android device. 29 | * 30 | * See [testing documentation](http://d.android.com/tools/testing). 31 | */ 32 | @RunWith(AndroidJUnit4::class) 33 | class ExampleInstrumentedTest { 34 | @Test 35 | fun useAppContext() { 36 | // Context of the app under test. 37 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 38 | assertEquals("com.utsman.smartmarker.sample", appContext.packageName) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/utsman/smartmarker/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.utsman.smartmarker.sample 18 | 19 | import android.location.Location 20 | import android.os.Bundle 21 | import androidx.appcompat.app.AppCompatActivity 22 | import com.google.android.gms.maps.CameraUpdateFactory 23 | import com.google.android.gms.maps.GoogleMap 24 | import com.google.android.gms.maps.SupportMapFragment 25 | import com.google.android.gms.maps.model.Marker 26 | import com.google.android.gms.maps.model.MarkerOptions 27 | import com.mapbox.mapboxsdk.Mapbox 28 | import com.mapbox.mapboxsdk.camera.CameraPosition 29 | import com.mapbox.mapboxsdk.maps.MapView 30 | import com.mapbox.mapboxsdk.maps.MapboxMap 31 | import com.mapbox.mapboxsdk.maps.Style 32 | import com.utsman.smartmarker.SmartMarker 33 | import com.utsman.smartmarker.googlemaps.bitmapFromVector 34 | import com.utsman.smartmarker.googlemaps.toLatLngGoogle 35 | import com.utsman.smartmarker.location.LocationUpdateListener 36 | import com.utsman.smartmarker.location.LocationWatcher 37 | import com.utsman.smartmarker.mapbox.addMarker 38 | import com.utsman.smartmarker.mapbox.toLatLngMapbox 39 | import com.utsman.smartmarker.moveMarkerSmoothly 40 | import io.reactivex.Observable 41 | import io.reactivex.android.schedulers.AndroidSchedulers 42 | import io.reactivex.disposables.CompositeDisposable 43 | import io.reactivex.schedulers.Schedulers 44 | import kotlinx.android.synthetic.main.activity_main.* 45 | import java.util.concurrent.TimeUnit 46 | 47 | class MainActivity : AppCompatActivity() { 48 | 49 | private lateinit var locationWatcher: LocationWatcher 50 | private var googleMarker: Marker? = null 51 | private var mapboxMarker: com.utsman.smartmarker.mapbox.Marker? = null 52 | 53 | private var googleMap: GoogleMap? = null 54 | private var mapboxMap: MapboxMap? = null 55 | 56 | private val disposable = CompositeDisposable() 57 | 58 | override fun onCreate(savedInstanceState: Bundle?) { 59 | super.onCreate(savedInstanceState) 60 | Mapbox.getInstance(this, "sk.eyJ1Ijoia3VjaW5nYXBlcyIsImEiOiJjazMxaTMwdnUwNmZhM2RxZnN3MXB3NXVxIn0.SbImlZrtwRkxSpk-1h0h3A") 61 | setContentView(R.layout.activity_main) 62 | 63 | locationWatcher = LocationWatcher(this) 64 | val googleMapsView = (google_map_view as SupportMapFragment) 65 | val mapboxMapsView = findViewById(R.id.mapbox_view) 66 | 67 | 68 | // get location once time 69 | locationWatcher.getLocation(this) { loc -> 70 | 71 | // google maps async 72 | googleMapsView.getMapAsync { map -> 73 | googleMap = map 74 | 75 | val markerOption = MarkerOptions() 76 | .position(loc.toLatLngGoogle()) 77 | .icon(bitmapFromVector(this@MainActivity, R.drawable.ic_marker_direction_2)) 78 | 79 | googleMarker = map.addMarker(markerOption) 80 | 81 | 82 | map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc.toLatLngGoogle(), 17f)) 83 | } 84 | 85 | // mapbox async 86 | mapboxMapsView.getMapAsync { map -> 87 | mapboxMap = map 88 | 89 | map.setStyle(Style.OUTDOORS) { style -> 90 | /** 91 | * version 0.0.3 92 | * */ 93 | /*val markerUtil = com.utsman.smartmarker.mapbox.MarkerOptions(this, style) 94 | mapboxMarker = markerUtil.addMarker("driver", R.drawable.ic_marker_direction_2, true, loc.toLatLngMapbox())*/ 95 | /** 96 | * End version 0.0.3 97 | * */ 98 | 99 | /** 100 | * version 1.0.3 use MarkerOptions 101 | * */ 102 | val markerOptions = com.utsman.smartmarker.mapbox.MarkerOptions.Builder() 103 | .setId("id") 104 | .setIcon(R.drawable.mapbox_marker_icon_default) 105 | .setPosition(loc.toLatLngMapbox()) 106 | .build(this) 107 | 108 | val bnd = com.mapbox.mapboxsdk.geometry.LatLng(-6.914744, 107.609810) 109 | val jgkt = com.mapbox.mapboxsdk.geometry.LatLng(-7.797068, 110.370529) 110 | val bks = com.mapbox.mapboxsdk.geometry.LatLng(-6.241586, 106.992416) 111 | val btn = com.mapbox.mapboxsdk.geometry.LatLng(-6.120000, 106.150276) 112 | 113 | val markerOptions1 = com.utsman.smartmarker.mapbox.MarkerOptions.Builder() 114 | .setId("jgja") 115 | .setIcon(R.drawable.ic_marker_direction_2, true) 116 | .setPosition(jgkt) 117 | .build(this) 118 | 119 | val markerOptions2 = com.utsman.smartmarker.mapbox.MarkerOptions.Builder() 120 | .setId("bks") 121 | .setIcon(R.drawable.ic_marker_direction_2, true) 122 | .setPosition(bks) 123 | .build(this) 124 | 125 | val markerOptions3 = com.utsman.smartmarker.mapbox.MarkerOptions.Builder() 126 | .setId("btn") 127 | .setPosition(btn) 128 | .build(this) 129 | 130 | //val markers = map.addMarkers(markerOptions1, markerOptions2, markerOptions3) 131 | 132 | val marker = map.addMarker(markerOptions3) 133 | 134 | btn_test.setOnClickListener { 135 | 136 | //markers.getId("btn").moveMarkerSmoothly(bks) 137 | marker?.moveMarkerSmoothly(bks) 138 | 139 | /*markers.filter { 140 | it.getId() != "bks" 141 | }.apply { 142 | map { 143 | it.moveMarkerSmoothly(bnd) 144 | } 145 | }*/ 146 | } 147 | 148 | 149 | 150 | //val bndMarker = map.addMarker(markerOptions1) 151 | 152 | val position = CameraPosition.Builder() 153 | .target(loc.toLatLngMapbox()) 154 | .zoom(15.0) 155 | .build() 156 | 157 | map.animateCamera(com.mapbox.mapboxsdk.camera.CameraUpdateFactory.newCameraPosition(position)) 158 | } 159 | } 160 | } 161 | 162 | // update camera to marker every 5 second 163 | timer { 164 | //googleMap?.animateCamera(CameraUpdateFactory.newLatLngZoom(it.toLatLngGoogle(), 17f)) 165 | val position = CameraPosition.Builder() 166 | .target(it.toLatLngMapbox()) 167 | .zoom(15.0) 168 | .build() 169 | 170 | //mapboxMap?.animateCamera(com.mapbox.mapboxsdk.camera.CameraUpdateFactory.newCameraPosition(position)) 171 | } 172 | 173 | // update your location 174 | updateLocation() 175 | } 176 | 177 | private fun updateLocation() { 178 | locationWatcher.getLocationUpdate(this, LocationWatcher.Priority.HIGH, object : LocationUpdateListener { 179 | override fun oldLocation(oldLocation: Location) { 180 | 181 | } 182 | 183 | override fun newLocation(newLocation: Location) { 184 | googleMarker?.moveMarkerSmoothly(newLocation.toLatLngGoogle()) 185 | 186 | 187 | mapboxMarker?.let { marker -> 188 | SmartMarker.moveMarkerSmoothly(marker, newLocation.toLatLngMapbox()) 189 | } 190 | } 191 | 192 | override fun failed(throwable: Throwable?) { 193 | } 194 | }) 195 | } 196 | 197 | private fun timer(ready: (Location) -> Unit) { 198 | val obs = Observable.interval(5000, TimeUnit.MILLISECONDS) 199 | .subscribeOn(Schedulers.io()) 200 | .observeOn(AndroidSchedulers.mainThread()) 201 | .subscribe { 202 | locationWatcher.getLocation(this) { 203 | ready.invoke(it) 204 | } 205 | } 206 | 207 | disposable.add(obs) 208 | } 209 | 210 | override fun onDestroy() { 211 | locationWatcher.stopLocationWatcher() 212 | disposable.dispose() 213 | super.onDestroy() 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /app/src/main/java/com/utsman/smartmarker/sample/SimpleActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.utsman.smartmarker.sample 18 | 19 | import android.os.Bundle 20 | import androidx.appcompat.app.AppCompatActivity 21 | import com.mapbox.mapboxsdk.Mapbox 22 | import com.mapbox.mapboxsdk.maps.Style 23 | import com.utsman.smartmarker.location.LocationWatcher 24 | import com.utsman.smartmarker.mapbox.MarkerOptions 25 | import com.utsman.smartmarker.mapbox.addMarker 26 | import com.utsman.smartmarker.mapbox.toLatLngMapbox 27 | import kotlinx.android.synthetic.main.activity_simple.* 28 | 29 | class SimpleActivity : AppCompatActivity() { 30 | 31 | override fun onCreate(savedInstanceState: Bundle?) { 32 | super.onCreate(savedInstanceState) 33 | Mapbox.getInstance(this, "sk.eyJ1Ijoia3VjaW5nYXBlcyIsImEiOiJjazMxaTMwdnUwNmZhM2RxZnN3MXB3NXVxIn0.SbImlZrtwRkxSpk-1h0h3A") 34 | setContentView(R.layout.activity_simple) 35 | 36 | val locationWatcher = LocationWatcher(this) 37 | locationWatcher.getLocation(this) { 38 | 39 | mapbox_view.getMapAsync { mapboxMap -> 40 | mapboxMap.setStyle(Style.MAPBOX_STREETS) { style -> 41 | 42 | val latlng = it.toLatLngMapbox() 43 | 44 | val markerOptions = MarkerOptions.Builder() 45 | .setId("layer-id") 46 | .setIcon(R.drawable.ic_marker_direction_2, true) 47 | .setPosition(latlng) 48 | .build(this) 49 | 50 | val marker = mapboxMap.addMarker(markerOptions) 51 | 52 | btn_test.setOnClickListener { 53 | style.removeLayer(marker.getId()) 54 | } 55 | 56 | 57 | 58 | mapboxMap.addOnMapLongClickListener { 59 | marker.moveMarkerSmoothly(it) 60 | true 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /app/src/main/java/com/utsman/smartmarker/sample/TrackerMapboxActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.utsman.smartmarker.sample 18 | 19 | import android.location.Location 20 | import android.os.Bundle 21 | import android.os.Handler 22 | import androidx.appcompat.app.AppCompatActivity 23 | import com.mapbox.android.gestures.RotateGestureDetector 24 | import com.mapbox.mapboxsdk.Mapbox 25 | import com.mapbox.mapboxsdk.camera.CameraPosition 26 | import com.mapbox.mapboxsdk.camera.CameraUpdateFactory 27 | import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions 28 | import com.mapbox.mapboxsdk.location.LocationComponentOptions 29 | import com.mapbox.mapboxsdk.location.modes.CameraMode 30 | import com.mapbox.mapboxsdk.location.modes.RenderMode 31 | import com.mapbox.mapboxsdk.maps.MapboxMap 32 | import com.mapbox.mapboxsdk.maps.Style 33 | import com.mapbox.mapboxsdk.style.layers.SymbolLayer 34 | import com.utsman.smartmarker.location.LocationUpdateListener 35 | import com.utsman.smartmarker.location.LocationWatcher 36 | import com.utsman.smartmarker.mapbox.* 37 | import io.reactivex.Observable 38 | import io.reactivex.android.schedulers.AndroidSchedulers 39 | import io.reactivex.disposables.CompositeDisposable 40 | import io.reactivex.schedulers.Schedulers 41 | import kotlinx.android.synthetic.main.activity_tracker_mapbox.* 42 | import java.util.concurrent.TimeUnit 43 | 44 | class TrackerMapboxActivity : AppCompatActivity() { 45 | 46 | private val locationWatcher by lazy { 47 | LocationWatcher(this) 48 | } 49 | 50 | private val compositeDisposable = CompositeDisposable() 51 | 52 | private var marker1: Marker? = null 53 | private lateinit var marker2: Marker 54 | 55 | override fun onCreate(savedInstanceState: Bundle?) { 56 | super.onCreate(savedInstanceState) 57 | Mapbox.getInstance(this, "sk.eyJ1Ijoia3VjaW5nYXBlcyIsImEiOiJjazMxaTMwdnUwNmZhM2RxZnN3MXB3NXVxIn0.SbImlZrtwRkxSpk-1h0h3A") 58 | setContentView(R.layout.activity_tracker_mapbox) 59 | 60 | mapbox_view_1.getMapAsync { mapboxMap -> 61 | mapboxMap.setStyle(Style.OUTDOORS) { style -> 62 | 63 | val updatePosition = CameraPosition.Builder() 64 | .zoom(17.0) 65 | .build() 66 | 67 | mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(updatePosition)) 68 | 69 | val locationComponentOption = LocationComponentOptions.builder(this) 70 | .bearingTintColor(R.color.colorPrimary) 71 | //.accuracyAlpha(0.8f) // 0.0f - 1.0f 72 | .build() 73 | 74 | val locationComponentActivationOptions = LocationComponentActivationOptions 75 | .builder(this, style) 76 | .locationComponentOptions(locationComponentOption) 77 | .useDefaultLocationEngine(true) 78 | .build() 79 | 80 | val locationComponent = mapboxMap.locationComponent 81 | locationComponent.activateLocationComponent(locationComponentActivationOptions) 82 | 83 | locationComponent.isLocationComponentEnabled = true 84 | locationComponent.cameraMode = CameraMode.TRACKING_GPS 85 | locationComponent.renderMode = RenderMode.GPS 86 | 87 | 88 | timer { 89 | moveCamera(it, mapboxMap) 90 | } 91 | } 92 | } 93 | 94 | mapbox_view_2.getMapAsync { mapboxMap -> 95 | 96 | mapboxMap.setStyle(Style.OUTDOORS) { style -> 97 | 98 | locationWatcher.getLocation(this) { location -> 99 | val markerOptions = MarkerOptions.Builder() 100 | .setId("id", true) 101 | .setIcon(R.drawable.ic_marker_direction_2, true) 102 | .setPosition(location.toLatLngMapbox()) 103 | .build(this) 104 | 105 | marker1 = mapboxMap.addMarker(markerOptions) 106 | 107 | moveCamera(location, mapboxMap) 108 | updateLocation() 109 | 110 | mapboxMap.addOnRotateListener(object : MapboxMap.OnRotateListener { 111 | override fun onRotate(detector: RotateGestureDetector) { 112 | 113 | } 114 | 115 | override fun onRotateEnd(detector: RotateGestureDetector) { 116 | toast("rotation --> ${mapboxMap.cameraPosition.bearing}") 117 | logi("rotation --> ${mapboxMap.cameraPosition.bearing}") 118 | } 119 | 120 | override fun onRotateBegin(detector: RotateGestureDetector) { 121 | 122 | } 123 | 124 | }) 125 | 126 | timer { 127 | moveCamera(it, mapboxMap) 128 | } 129 | } 130 | } 131 | } 132 | 133 | mapbox_view_3.getMapAsync { mapboxMap -> 134 | mapboxMap.setStyle(Style.OUTDOORS) { style -> 135 | 136 | locationWatcher.getLocation(this) { location -> 137 | 138 | val markerOptions = MarkerOptions.Builder() 139 | .setId("layer-id") 140 | .setIcon(R.drawable.ic_marker_direction_2, true) 141 | .setPosition(location.toLatLngMapbox()) 142 | .build(this) 143 | 144 | marker2 = mapboxMap.addMarker(markerOptions) 145 | logi("marker is --> ${marker2.getId()}") 146 | 147 | moveCamera(location, mapboxMap) 148 | updateLocation() 149 | 150 | mapboxMap.addOnRotateListener(object : MapboxMap.OnRotateListener { 151 | override fun onRotate(detector: RotateGestureDetector) { 152 | 153 | } 154 | 155 | override fun onRotateEnd(detector: RotateGestureDetector) { 156 | toast("rotation --> ${mapboxMap.cameraPosition.bearing}") 157 | logi("rotation --> ${mapboxMap.cameraPosition.bearing}") 158 | } 159 | 160 | override fun onRotateBegin(detector: RotateGestureDetector) { 161 | 162 | } 163 | 164 | }) 165 | 166 | Handler().postDelayed({ 167 | toast("start remove marker --> ${marker2.getId()}") 168 | //style.removeImage(marker2?.getId()!!) 169 | //style.removeMarker(marker2!!) 170 | //style.removeLayer 171 | 172 | //style.removeLayer(marker2.getId()) 173 | //style.layers.clear() 174 | //markerOptions.removeMe() 175 | style.removeLayer("layer-id") 176 | }, 5000) 177 | 178 | val updatePosition = CameraPosition.Builder() 179 | .zoom(17.0) 180 | .build() 181 | 182 | mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(updatePosition)) 183 | 184 | val locationComponentOption = LocationComponentOptions.builder(this) 185 | .bearingTintColor(R.color.colorPrimary) 186 | //.accuracyAlpha(0.8f) // 0.0f - 1.0f 187 | .build() 188 | 189 | val locationComponentActivationOptions = LocationComponentActivationOptions 190 | .builder(this, style) 191 | .locationComponentOptions(locationComponentOption) 192 | .useDefaultLocationEngine(true) 193 | .build() 194 | 195 | val locationComponent = mapboxMap.locationComponent 196 | locationComponent.activateLocationComponent(locationComponentActivationOptions) 197 | 198 | locationComponent.isLocationComponentEnabled = true 199 | locationComponent.cameraMode = CameraMode.TRACKING_GPS 200 | locationComponent.renderMode = RenderMode.GPS 201 | 202 | timer { 203 | moveCamera(it, mapboxMap) 204 | } 205 | } 206 | } 207 | 208 | } 209 | } 210 | 211 | private fun moveCamera(it: Location, mapboxMap: MapboxMap) { 212 | val updatePosition = CameraPosition.Builder() 213 | .target(it.toLatLngMapbox()) 214 | .zoom(17.0) 215 | .build() 216 | 217 | mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(updatePosition)) 218 | } 219 | 220 | private fun updateLocation() { 221 | locationWatcher.getLocationUpdate(LocationWatcher.Priority.JEDI, object : LocationUpdateListener { 222 | override fun oldLocation(oldLocation: Location) { 223 | 224 | } 225 | 226 | override fun newLocation(newLocation: Location) { 227 | marker1?.moveMarkerSmoothly(newLocation.toLatLngMapbox()) 228 | marker2?.moveMarkerSmoothly(newLocation.toLatLngMapbox()) 229 | } 230 | 231 | override fun failed(throwable: Throwable) { 232 | 233 | } 234 | 235 | }) 236 | } 237 | 238 | private fun timer(ready: (Location) -> Unit) { 239 | val obs = Observable.interval(5000, TimeUnit.MILLISECONDS) 240 | .subscribeOn(Schedulers.io()) 241 | .observeOn(AndroidSchedulers.mainThread()) 242 | .subscribe { 243 | locationWatcher.getLocation(this) { 244 | ready.invoke(it) 245 | } 246 | } 247 | 248 | compositeDisposable.add(obs) 249 | } 250 | 251 | override fun onDestroy() { 252 | super.onDestroy() 253 | compositeDisposable.dispose() 254 | locationWatcher.stopLocationWatcher() 255 | } 256 | } -------------------------------------------------------------------------------- /app/src/main/java/com/utsman/smartmarker/sample/ext.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Muhammad Utsman 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.utsman.smartmarker.sample 18 | 19 | import android.content.Context 20 | import android.util.Log 21 | import android.widget.Toast 22 | 23 | fun logi(msg: String?) = Log.i("anjay", msg) 24 | fun loge(msg: String?) = Log.e("anjay", msg) 25 | 26 | fun Context.toast(msg: String) = Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 23 | 28 | 29 | 35 | 38 | 41 | 42 | 43 | 44 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_marker_direction_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | 24 | 26 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 176 | 181 | 186 | 187 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 26 | 27 | 33 | 34 | 41 | 42 |