├── .gitignore ├── .gitmodules ├── LICENCE.txt ├── README.md ├── android-sdk ├── .gitignore ├── build.gradle ├── pom.xml ├── proguard-rules.pro └── src │ ├── androidTest │ ├── assets │ │ ├── mapfit-base-theme.yaml │ │ └── mapfit-custom-test.yaml │ └── java │ │ └── com │ │ └── mapfit │ │ └── android │ │ ├── BuildingExtrutionTest.kt │ │ ├── CameraTest.kt │ │ ├── DirectionsTest.kt │ │ ├── GeocoderTest.kt │ │ ├── LayerTest.kt │ │ ├── MapViewTestActivity.kt │ │ ├── TestUtils.kt │ │ ├── annotations │ │ ├── MarkerTest.kt │ │ ├── PolygonTest.kt │ │ ├── PolylineAnimationTest.kt │ │ └── PolylineTest.kt │ │ └── map │ │ ├── MapListenersTest.kt │ │ ├── MapOptionsTest.kt │ │ ├── MapViewTest.kt │ │ └── MapViewUiControlsTest.kt │ ├── debug │ └── AndroidManifest.xml │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── androidPlatform.cpp │ │ ├── androidPlatform.h │ │ ├── jniExports.cpp │ │ ├── sqlite3ndk.cpp │ │ └── sqlite3ndk.h │ ├── java │ │ └── com │ │ │ ├── almeros │ │ │ └── android │ │ │ │ └── multitouch │ │ │ │ ├── BaseGestureDetector.java │ │ │ │ ├── MoveGestureDetector.java │ │ │ │ ├── RotateGestureDetector.java │ │ │ │ ├── ShoveGestureDetector.java │ │ │ │ └── TwoFingerGestureDetector.java │ │ │ └── mapfit │ │ │ ├── android │ │ │ ├── BuildingExtruder.kt │ │ │ ├── DirectionsOptions.kt │ │ │ ├── Layer.kt │ │ │ ├── MapController.java │ │ │ ├── MapData.kt │ │ │ ├── MapOptions.kt │ │ │ ├── MapTheme.kt │ │ │ ├── MapView.kt │ │ │ ├── Mapfit.kt │ │ │ ├── MapfitMap.kt │ │ │ ├── OnMapClickListener.kt │ │ │ ├── OnMapDoubleClickListener.kt │ │ │ ├── OnMapLongClickListener.kt │ │ │ ├── OnMapPanListener.kt │ │ │ ├── OnMapPinchListener.kt │ │ │ ├── OnMapReadyCallback.kt │ │ │ ├── OnMapThemeLoadListener.kt │ │ │ ├── anim │ │ │ │ ├── Animation.kt │ │ │ │ ├── AnimationListener.kt │ │ │ │ ├── AnimationOptions.kt │ │ │ │ ├── RouteEvaluator.kt │ │ │ │ └── polyline │ │ │ │ │ ├── PolylineAnimation.kt │ │ │ │ │ ├── SnakeAnimation.kt │ │ │ │ │ └── SnakeAnimationOptions.kt │ │ │ ├── annotations │ │ │ │ ├── Anchor.kt │ │ │ │ ├── Annotation.kt │ │ │ │ ├── Building.kt │ │ │ │ ├── BuildingOptions.kt │ │ │ │ ├── CapType.kt │ │ │ │ ├── JoinType.kt │ │ │ │ ├── MapfitMarker.kt │ │ │ │ ├── Marker.kt │ │ │ │ ├── MarkerOptions.kt │ │ │ │ ├── OnAnnotationClickListener.kt │ │ │ │ ├── PolyFeature.kt │ │ │ │ ├── PolyPointAnnotationOptions.kt │ │ │ │ ├── Polygon.kt │ │ │ │ ├── PolygonOptions.kt │ │ │ │ ├── Polyline.kt │ │ │ │ ├── PolylineOptions.kt │ │ │ │ ├── callback │ │ │ │ │ ├── OnMarkerAddedCallback.kt │ │ │ │ │ ├── OnMarkerClickListener.kt │ │ │ │ │ ├── OnPolygonClickListener.kt │ │ │ │ │ └── OnPolylineClickListener.kt │ │ │ │ └── widget │ │ │ │ │ └── PlaceInfo.kt │ │ │ ├── camera │ │ │ │ ├── CameraAnimation.kt │ │ │ │ ├── CameraOptions.kt │ │ │ │ ├── Cinematography.kt │ │ │ │ ├── OrbitAnimation.kt │ │ │ │ └── OrbitTrajectory.kt │ │ │ ├── compass │ │ │ │ ├── CompassListener.kt │ │ │ │ └── CompassProvider.kt │ │ │ ├── directions │ │ │ │ ├── Directions.kt │ │ │ │ ├── DirectionsCallback.kt │ │ │ │ ├── DirectionsParser.kt │ │ │ │ ├── DirectionsType.kt │ │ │ │ └── model │ │ │ │ │ ├── Leg.kt │ │ │ │ │ ├── Location.kt │ │ │ │ │ ├── Maneuver.kt │ │ │ │ │ ├── Route.kt │ │ │ │ │ ├── Summary.kt │ │ │ │ │ └── Trip.kt │ │ │ ├── exceptions │ │ │ │ ├── MapfitAuthorizationException.kt │ │ │ │ └── MapfitConfigurationException.kt │ │ │ ├── geocoder │ │ │ │ ├── GeocodeParser.kt │ │ │ │ ├── Geocoder.kt │ │ │ │ ├── GeocoderCallback.kt │ │ │ │ └── model │ │ │ │ │ ├── Address.kt │ │ │ │ │ ├── Building.kt │ │ │ │ │ ├── Entrance.kt │ │ │ │ │ ├── EntranceType.kt │ │ │ │ │ └── ResponseType.kt │ │ │ ├── geometry │ │ │ │ ├── GeoExtentions.kt │ │ │ │ ├── GeoUtils.kt │ │ │ │ ├── LatLng.kt │ │ │ │ └── LatLngBounds.kt │ │ │ ├── location │ │ │ │ ├── LocationListener.kt │ │ │ │ ├── LocationPriority.kt │ │ │ │ ├── LocationRequest.kt │ │ │ │ ├── LocationUtils.kt │ │ │ │ ├── MapfitLocationProvider.kt │ │ │ │ └── ProviderStatus.kt │ │ │ └── utils │ │ │ │ ├── CommonExtentions.kt │ │ │ │ ├── CommonUtils.kt │ │ │ │ ├── DebugUtils.kt │ │ │ │ ├── Loggers.kt │ │ │ │ └── PolyUtils.kt │ │ │ └── tetragon │ │ │ ├── CachePolicy.java │ │ │ ├── ConfigChooser.java │ │ │ ├── FontFileParser.java │ │ │ ├── HttpHandler.java │ │ │ ├── LabelPickResult.java │ │ │ ├── MarkerPickResult.java │ │ │ ├── SceneError.java │ │ │ ├── SceneUpdate.kt │ │ │ └── TouchInput.java │ └── res │ │ ├── drawable-hdpi │ │ ├── mf_card_backing.png │ │ ├── mf_compass.png │ │ ├── mf_current_location.png │ │ ├── mf_current_location_passive.png │ │ ├── mf_re_center.png │ │ ├── mf_re_center_off.png │ │ └── mf_user_loc.png │ │ ├── drawable-mdpi │ │ ├── mf_compass.png │ │ ├── mf_current_location.png │ │ ├── mf_current_location_passive.png │ │ ├── mf_re_center.png │ │ ├── mf_re_center_off.png │ │ └── mf_user_loc.png │ │ ├── drawable-xhdpi │ │ ├── mf_card_backing.png │ │ ├── mf_compass.png │ │ ├── mf_current_location.png │ │ ├── mf_current_location_passive.png │ │ ├── mf_re_center.png │ │ ├── mf_re_center_off.png │ │ └── mf_user_loc.png │ │ ├── drawable-xxhdpi │ │ ├── mf_card_backing.png │ │ ├── mf_compass.png │ │ ├── mf_current_location.png │ │ ├── mf_current_location_passive.png │ │ ├── mf_re_center.png │ │ ├── mf_re_center_off.png │ │ └── mf_user_loc.png │ │ ├── drawable-xxxhdpi │ │ ├── mf_compass.png │ │ ├── mf_current_location.png │ │ ├── mf_current_location_passive.png │ │ ├── mf_place_info_bg.png │ │ ├── mf_re_center.png │ │ ├── mf_re_center_off.png │ │ └── mf_user_loc.png │ │ ├── drawable │ │ ├── mf_accuracy_circle.xml │ │ ├── mf_marker_dot.xml │ │ ├── mf_transparent.xml │ │ ├── mf_user_direction.xml │ │ ├── mf_watermark_dark.xml │ │ ├── mf_watermark_light.xml │ │ ├── mf_watermarklight.png │ │ ├── mf_zoom_bg.png │ │ ├── mf_zoom_break.xml │ │ ├── mf_zoom_in.xml │ │ └── mf_zoom_out.xml │ │ ├── layout │ │ ├── mf_overlay_map_controls.xml │ │ └── mf_widget_place_info.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ └── strings.xml │ └── test │ ├── java │ └── com │ │ └── mapfit │ │ └── android │ │ ├── GeocoderParserTest.kt │ │ ├── MapfitTest.kt │ │ ├── UtilsTest.kt │ │ └── geometry │ │ ├── LatLngBoundsTest.kt │ │ └── LatLngTest.kt │ └── resources │ └── mockito-extensions │ └── org.mockito.plugins.MockMaker ├── assets └── Android-banner.png ├── build.gradle ├── gradle.properties ├── gradle ├── dokka.gradle ├── jcenter-push.gradle ├── mapfit-tasks.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── mapfit │ │ └── mapfitdemo │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── dummy_coffee_shops.json │ │ ├── sample-base-theme.yaml │ │ └── sample.yaml │ ├── java │ │ └── com │ │ │ └── mapfit │ │ │ └── demo │ │ │ ├── App.kt │ │ │ ├── CustomYamlActivity.kt │ │ │ ├── GeocoderActivity.kt │ │ │ ├── JavaActivity.java │ │ │ ├── KotlinActivity.kt │ │ │ ├── PolyStylingActivity.kt │ │ │ └── UserLocationActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_lab.xml │ │ ├── activity_main.xml │ │ └── widget_custom_place_info.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-v21 │ │ └── styles.xml │ │ └── values │ │ ├── api_key.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── mapfit │ └── mapfitdemo │ └── ExampleUnitTest.kt └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | .build 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /app/build 11 | *.aar 12 | /mapfit-gl/ 13 | /sample/src/main/java/com/mapfit/demo/LabActivity.kt 14 | /sample/src/main/java/com/mapfit/demo/LabJavaActivity.java 15 | android-sdk/src/debug/ 16 | appcompat-v7/ 17 | gradle/gradle-wrapper.properties 18 | mapfit_local.properties 19 | /sample/src/debug/res/values/local_properties.xml 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "mapfit-gl"] 2 | path = mapfit-gl 3 | url = git@github.com:mapfit/mapfit-gl.git 4 | -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Copyright (c) 2018 Mapfit 4 | All Rights Reserved 5 | 6 | Use of this SDK is authorized only in accordance with Mapfit's Terms and Conditions and License Agreement. 7 | Go to www.mapfit.com for details. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Mapfit SDK for Android 3 | 4 | 5 | 6 | ## Get your Mapfit API key 7 | To use Mapfit Maps and services, your application will need an API key. You can get your API key for free [here](https://mapfit.com/getstarted). 8 | 9 | ## Install the Mapfit Android SDK 10 | Make sure `JCenter` is included in your repositories scope inside project level `build.gradle` file as follows 11 | ``` 12 | allprojects { 13 | repositories { 14 | jcenter() 15 | } 16 | } 17 | ``` 18 | 19 | In your module level `build.gradle` file, add depencency as follows. 20 | ``` 21 | dependencies { 22 | implementation 'com.mapfit:android-sdk:2.1.1' 23 | } 24 | ``` 25 | 26 | ## Adding a map to your view 27 | Inside your layout file, add `MapView` as follows 28 | 29 | ```xml 30 | 34 | ``` 35 | 36 | ## Initializing Mapfit 37 | Before using `MapView` or any other Mapfit services, you need to instantiate a `Mapfit` instance as follows 38 | 39 | #### Kotlin 40 | ```kotlin 41 | Mapfit.getInstance(context, YOUR_API_KEY) 42 | 43 | ``` 44 | 45 | #### Java 46 | ```java 47 | Mapfit.getInstance(context, YOUR_API_KEY); 48 | ``` 49 | 50 | ## Setup MapView and add your first Marker 51 | To show the map and interact with it, you must setup the `MapView` as follows 52 | 53 | #### Kotlin 54 | ```kotlin 55 | mapView.getMapAsync(onMapReadyCallback = object : OnMapReadyCallback { 56 | override fun onMapReady(mapfitMap: MapfitMap) { 57 | 58 | val position = LatLng(40.744023, -73.993150) 59 | val marker= mapfitMap.addMarker(position) 60 | 61 | } 62 | }) 63 | ``` 64 | 65 | #### Java 66 | ```java 67 | mapView.getMapAsync(new OnMapReadyCallback() { 68 | @Override 69 | public void onMapReady(MapfitMap mapfitMap) { 70 | 71 | LatLng position = new LatLng(40.744023, -73.993150); 72 | Marker marker = mapfitMap.addMarker(position); 73 | 74 | } 75 | }); 76 | ``` 77 | 78 | If you are looking for detailed documentation, please see [Mapfit Documentation](https://mapfit-android.readme.io/docs). 79 | 80 | 81 | ## License 82 | Copyright (c) 2018 Mapfit, Inc. 83 | All Rights Reserved. 84 | 85 | -------------------------------------------------------------------------------- /android-sdk/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | /mapfit-gl/ 10 | mapfit_local.properties 11 | sample/src/main/java/com/mapfit/demo/LabActivity.kt 12 | mapfit-gl 13 | -------------------------------------------------------------------------------- /android-sdk/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: "org.jetbrains.kotlin.android.extensions" 4 | 5 | 6 | ext.mapfit = [ 7 | 'sdk_version' : '2.1.1', 8 | 'sdk_version_code' : 15, 9 | 'compile_sdk_version': 27, 10 | 'build_tools_version': '27.0.3', 11 | 'min_sdk_version' : 16, 12 | 'target_sdk_version' : 27 13 | ] 14 | 15 | android { 16 | compileSdkVersion project.mapfit.compile_sdk_version 17 | buildToolsVersion project.mapfit.build_tools_version 18 | 19 | defaultConfig { 20 | minSdkVersion project.mapfit.min_sdk_version 21 | targetSdkVersion project.mapfit.target_sdk_Version 22 | versionName project.mapfit.sdk_version 23 | versionCode project.mapfit.sdk_version_code 24 | 25 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 26 | 27 | androidExtensions { 28 | experimental = true 29 | } 30 | 31 | externalNativeBuild { 32 | cmake { 33 | targets 'tangram' 34 | arguments '-DTANGRAM_PLATFORM=android', 35 | '-DANDROID_TOOLCHAIN=clang', 36 | '-DANDROID_STL=c++_shared' 37 | cppFlags '-std=c++14', 38 | '-pedantic', 39 | '-fPIC', 40 | '-fexceptions', 41 | '-frtti', 42 | //warnings 43 | '-Wall', 44 | '-Wignored-qualifiers', 45 | '-Wtype-limits', 46 | '-Wmissing-field-initializers', 47 | '-Wno-format-pedantic' 48 | 49 | abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86' 50 | } 51 | } 52 | } 53 | 54 | externalNativeBuild { 55 | cmake { 56 | path '../mapfit-gl/CMakeLists.txt' 57 | } 58 | } 59 | 60 | sourceSets { 61 | main.java.srcDirs += 'src/main/kotlin' 62 | test.java.srcDirs += 'src/test/kotlin' 63 | androidTest.java.srcDirs += 'src/androidTest/kotlin' 64 | } 65 | 66 | buildTypes { 67 | 68 | release { 69 | buildConfigField "Boolean", "DEBUG_MODE", "false" 70 | externalNativeBuild { 71 | cmake.cppFlags '-g0' 72 | } 73 | } 74 | 75 | debug { 76 | buildConfigField "Boolean", "DEBUG_MODE", "false" 77 | externalNativeBuild { 78 | cmake.cppFlags '-g' 79 | } 80 | } 81 | 82 | } 83 | 84 | defaultConfig { 85 | multiDexEnabled true 86 | vectorDrawables.useSupportLibrary = true 87 | } 88 | 89 | testOptions { 90 | unitTests.returnDefaultValues = true 91 | } 92 | 93 | lintOptions { 94 | abortOnError false 95 | } 96 | 97 | kapt { generateStubs = true } 98 | 99 | } 100 | 101 | dependencies { 102 | api fileTree(include: ['*.jar'], dir: 'libs') 103 | api "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}" 104 | api "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}" 105 | api "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlin_coroutine}" 106 | api "com.android.support:appcompat-v7:${versions.support_lib}" 107 | api "com.android.support:support-annotations:${versions.support_lib_version}" 108 | api "com.squareup.okhttp3:okhttp:${versions.okHttp}" 109 | api "com.squareup.okhttp3:logging-interceptor:${versions.okHttp}" 110 | api "com.squareup.moshi:moshi-kotlin:${versions.moshi}" 111 | 112 | testImplementation 'junit:junit:4.12' 113 | testImplementation 'org.json:json:20140107' 114 | testImplementation "org.mockito:mockito-core:${versions.mockito}" 115 | testImplementation "org.mockito:mockito-inline:${versions.mockito}" 116 | testImplementation "com.squareup.okhttp3:mockwebserver:${versions.okHttp}" 117 | androidTestImplementation "org.mockito:mockito-android:${versions.mockito}" 118 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 119 | androidTestImplementation 'com.android.support.test:rules:1.0.2' 120 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 121 | androidTestImplementation 'com.android.support.test.espresso:espresso-idling-resource:3.0.2' 122 | } 123 | 124 | repositories { 125 | mavenCentral() 126 | } 127 | 128 | kotlin { 129 | experimental { 130 | coroutines "enable" 131 | } 132 | } 133 | 134 | if (project.rootProject.file('mapfit_local.properties').exists()) { 135 | apply from: file("${rootDir}/gradle/jcenter-push.gradle") 136 | } 137 | 138 | apply from: file("${rootDir}/gradle/mapfit-tasks.gradle") -------------------------------------------------------------------------------- /android-sdk/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 | 23 | 24 | 25 | # kotlin 26 | -keepclassmembernames class kotlinx.** { 27 | volatile ; 28 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/assets/mapfit-custom-test.yaml: -------------------------------------------------------------------------------- 1 | # Mapfit Day Theme 2 | # Last updated April 16, 2018 3 | 4 | import: 5 | - mapfit-base-theme.yaml 6 | 7 | global: 8 | 9 | ####### ALL COLOR VARIABLES ####### 10 | 11 | # TEXT 12 | text_fill: rgba(90, 95, 105, 1) 13 | text_outline: rgba(255, 255, 255,.75) 14 | text_fill_neighborhoods: rgba(143, 156, 179, 1) 15 | text_fill_water: rgba(71, 123, 198, 1) 16 | text_outline_water: rgba(255, 255, 255,.75) 17 | text_fill_parks: rgba(67, 162, 84, 1) 18 | text_outline_parks: rgba(189, 222, 197, 1) 19 | text_beach_fill: rgba(153, 144, 92, 1) 20 | text_beach_outline: rgba(255, 255, 255,.75) 21 | text_highway_fill: rgba(109, 51, 4, 1) 22 | text_highway_outline: rgba(255, 255, 255,.75) 23 | text_highway_exits: rgba(237, 152, 6, 1) 24 | text_signs_fill: rgba(255, 255, 255, 1) 25 | 26 | # ROADS 27 | highway_fill: rgba(255, 224, 115, 1) 28 | highway_outline: rgba(255, 202, 112,1) 29 | road_fill: rgba(255, 255, 255,1) 30 | road_outline: rgba(223, 223, 223,1) 31 | tunnel_fill: rgba(223, 223, 223,1) 32 | tunnel_outline: rgba(223, 223, 223,1) 33 | road_directional_arrows_fill: rgba(240, 240, 240,1) 34 | pedestrian_path_fill: rgba(255, 255, 255,1) 35 | pedestrian_path_outline: rgba(255, 255, 255,1) 36 | pedestrian_paths_in_park_fill: rgba(163,204,163,1) 37 | pedestrian_paths_in_universities_fill: rgba(219, 203, 152,1) 38 | pedestrian_steps_fill: rgba(242, 242, 242,1) 39 | roads_in_park_fill: rgba(189, 222, 197,1) 40 | roads_in_cemetary_fill: rgba(255, 255, 255,1) 41 | 42 | # WATER 43 | ocean_fill: rgba(137, 208, 255,1) 44 | water_fill: rgba(137, 208, 255,1) 45 | 46 | # LAND 47 | map_background_fill: rgba(255, 255, 255,1) 48 | land_fill: rgba(242, 242, 242,1) 49 | parks_fill: rgba(184, 233, 164,1) 50 | cemetary_fill: rgba(205, 238, 193,1) 51 | protected_area_fill: rgba(238, 237, 235,1) 52 | special_parks_fill: rgba(162, 223, 139,1) 53 | stadium_fill: rgba(191, 176, 142,1) 54 | playground_fill: rgba(215, 204, 176,1) 55 | beach_fill: rgba(235, 235, 201,1) 56 | military_fill: rgba(207, 209, 221,1) 57 | 58 | # BUILDINGS 59 | building_fill: rgba(235, 235, 235,1) 60 | building_outline: rgba(230, 230, 230,1) 61 | building_extruded_fill: rgba(125, 134, 224, 0.8) 62 | 63 | # AIRPORTS 64 | airport_road_fill: rgba(192, 195, 214,1) 65 | airport_land_fill: rgba(207, 209, 221,1) 66 | 67 | # EDUCATION 68 | university_fill: rgba(238, 227, 180,1) 69 | school_fill: rgba(242, 242, 242,1) 70 | 71 | # HOSPITALS 72 | hospital_fill: rgba(231, 204, 213,1) 73 | 74 | # FEATURES 75 | ferry_fill: rgba(124, 170, 203,1) 76 | railways_fill: rgba(223, 223, 223,1) 77 | special_pedestrian_area_fill: rgba(249, 246, 241,1) 78 | parking_fill: rgba(249, 246, 241,1) 79 | urbanization_fill: rgba(217, 196, 165,1) 80 | winter_sports_area_fill: rgba(236, 235, 232,1) 81 | tourism_area_fill: rgba(249, 246, 241,1) 82 | 83 | # BOUNDARIES 84 | region_boundary_fill: rgba(153, 153, 153,1) 85 | city_wall_fill: rgba(217, 196, 165,1) 86 | 87 | 88 | ####### ALL SHOW/HIDE VARIABLES ####### 89 | 90 | show_transit: false # public transit visibility 91 | show_3d_buildings: false # 3D building visibility 92 | show_special_areas: true # show commercial, retail, pedestrian areas 93 | show_parking_areas: true # show parking areas 94 | 95 | 96 | # CAMERA OPTIONS (IF 3D BUILDINGS ARE ON) 97 | 98 | cameras: 99 | master: 100 | type: perspective # choose between perspective, isometric, or flat 101 | 102 | textures: 103 | pois: 104 | url: https://cdn.mapfit.com/v2-3/themes/images/refill@2x.png 105 | -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/BuildingExtrutionTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.graphics.Color 4 | import android.support.test.annotation.UiThreadTest 5 | import android.support.test.espresso.IdlingRegistry 6 | import android.support.test.espresso.idling.CountingIdlingResource 7 | import android.support.test.rule.ActivityTestRule 8 | import android.support.test.runner.AndroidJUnit4 9 | import com.mapfit.android.geometry.LatLng 10 | import kotlinx.coroutines.experimental.delay 11 | import kotlinx.coroutines.experimental.runBlocking 12 | import org.junit.* 13 | import org.junit.runner.RunWith 14 | import org.mockito.MockitoAnnotations 15 | 16 | @RunWith(AndroidJUnit4::class) 17 | class BuildingExtrutionTest { 18 | 19 | private lateinit var mapfitMap: MapfitMap 20 | private lateinit var mapView: MapView 21 | 22 | private val latLng = LatLng(40.740939, -73.989676) 23 | 24 | private var idlingResource = CountingIdlingResource("building_idling_resource") 25 | 26 | @Rule 27 | @JvmField 28 | val activityRule: ActivityTestRule = ActivityTestRule( 29 | MapViewTestActivity::class.java, 30 | true, 31 | true 32 | ) 33 | 34 | 35 | @Before 36 | @UiThreadTest 37 | fun init() { 38 | MockitoAnnotations.initMocks(this) 39 | mapView = activityRule.activity.findViewById(R.id.mapView) 40 | 41 | mapfitMap = mapView.getMap(MapTheme.MAPFIT_DAY.toString()) 42 | mapfitMap.apply { 43 | setCenter(latLng) 44 | setZoom(19f) 45 | } 46 | 47 | IdlingRegistry.getInstance().register(idlingResource) 48 | } 49 | 50 | @After 51 | @UiThreadTest 52 | fun dispose() { 53 | Mapfit.dispose() 54 | IdlingRegistry.getInstance().unregister(idlingResource) 55 | } 56 | 57 | @Test 58 | fun testBuildingExtrution() = runBlocking { 59 | delay(500) 60 | mapfitMap.extrudeBuilding(latLng) 61 | delay(2000) 62 | 63 | var triple = Triple(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE) 64 | 65 | idlingResource.increment() 66 | mapView.getMapSnap(MapController.FrameCaptureCallback { 67 | val screenPosition = mapView.getScreenPosition(latLng) 68 | val pixel = it.getPixel(screenPosition.x.toInt(), screenPosition.y.toInt()) 69 | triple = Triple(Color.red(pixel), Color.green(pixel), Color.blue(pixel)) 70 | idlingResource.decrement() 71 | 72 | }) 73 | 74 | suspendViaGLSurface() 75 | Assert.assertEquals(235, triple.first) // light filters the color hence its not 255 76 | Assert.assertEquals(0, triple.second) 77 | Assert.assertEquals(0, triple.third) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/CameraTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.graphics.drawable.Animatable 4 | import android.support.test.annotation.UiThreadTest 5 | import android.support.test.espresso.IdlingRegistry 6 | import android.support.test.espresso.idling.CountingIdlingResource 7 | import android.support.test.rule.ActivityTestRule 8 | import android.support.test.runner.AndroidJUnit4 9 | import com.mapfit.android.anim.AnimationListener 10 | import com.mapfit.android.camera.Cinematography 11 | import com.mapfit.android.camera.OrbitTrajectory 12 | import com.mapfit.android.geometry.LatLng 13 | import junit.framework.Assert 14 | import org.junit.After 15 | import org.junit.Before 16 | import org.junit.Rule 17 | import org.junit.Test 18 | import org.junit.runner.RunWith 19 | import org.mockito.Mock 20 | import org.mockito.MockitoAnnotations 21 | 22 | @RunWith(AndroidJUnit4::class) 23 | class CameraTest { 24 | 25 | private lateinit var mapView: MapView 26 | 27 | private lateinit var mapfitMap: MapfitMap 28 | 29 | @Mock 30 | private lateinit var onMapPanListener: OnMapPanListener 31 | 32 | private val latLng = LatLng(40.7441855, -73.995394) 33 | private var idlingResource = CountingIdlingResource("anim_idling_resource") 34 | 35 | @Rule 36 | @JvmField 37 | val activityRule: ActivityTestRule = ActivityTestRule( 38 | MapViewTestActivity::class.java, 39 | true, 40 | true 41 | ) 42 | 43 | @Before 44 | @UiThreadTest 45 | fun init() { 46 | MockitoAnnotations.initMocks(this) 47 | 48 | mapView = activityRule.activity.findViewById(R.id.mapView) 49 | mapfitMap = mapView.getMap(MapTheme.MAPFIT_DAY.toString()) 50 | IdlingRegistry.getInstance().register(idlingResource) 51 | } 52 | 53 | @After 54 | fun dispose() { 55 | Mapfit.dispose() 56 | IdlingRegistry.getInstance().unregister(idlingResource) 57 | } 58 | 59 | @Test 60 | fun testOrbitAnimation() { 61 | val anim = Cinematography(mapfitMap) 62 | .create( 63 | OrbitTrajectory() 64 | .loop(false) 65 | .duration(1000) 66 | .pivot(latLng) 67 | , object : AnimationListener { 68 | override fun onStart(animatable: Animatable) { 69 | idlingResource.decrement() 70 | } 71 | 72 | override fun onFinish(animatable: Animatable) { 73 | idlingResource.decrement() 74 | } 75 | } 76 | ) 77 | 78 | idlingResource.increment() 79 | anim.start() 80 | suspendViaGLSurface() // wait for onStart 81 | 82 | idlingResource.increment() // wait for onFinish 83 | suspendViaGLSurface() 84 | 85 | Assert.assertNotSame(0f, mapfitMap.getRotation()) // check if camera rotated 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/DirectionsTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.annotation.UiThreadTest 5 | import android.support.test.runner.AndroidJUnit4 6 | import com.mapfit.android.directions.Directions 7 | import com.mapfit.android.directions.DirectionsCallback 8 | import com.mapfit.android.directions.DirectionsType 9 | import com.mapfit.android.directions.model.Route 10 | import com.mapfit.android.exceptions.MapfitConfigurationException 11 | import kotlinx.coroutines.experimental.delay 12 | import kotlinx.coroutines.experimental.runBlocking 13 | import org.junit.After 14 | import org.junit.Before 15 | import org.junit.Test 16 | import org.junit.runner.RunWith 17 | import org.mockito.ArgumentMatchers 18 | import org.mockito.Mock 19 | import org.mockito.Mockito 20 | import org.mockito.MockitoAnnotations 21 | import java.lang.Exception 22 | 23 | /** 24 | * Created by dogangulcan on 2/5/18. 25 | */ 26 | @RunWith(AndroidJUnit4::class) 27 | class DirectionsTest { 28 | 29 | @Mock 30 | private lateinit var directionsCallback: DirectionsCallback 31 | 32 | private val context = InstrumentationRegistry.getContext() 33 | 34 | @Before 35 | @UiThreadTest 36 | fun init() { 37 | MockitoAnnotations.initMocks(this) 38 | Mapfit.dispose() 39 | } 40 | 41 | @After 42 | fun dispose() { 43 | Mapfit.dispose() 44 | } 45 | 46 | 47 | @Test(expected = MapfitConfigurationException::class) 48 | @UiThreadTest 49 | fun testMapfitConfiguration() { 50 | val originAddress = "111 Macdougal Street new york ny" 51 | val destinationAddress = "119 W 24th Street new york ny" 52 | 53 | Directions().route( 54 | originAddress = originAddress, 55 | destinationAddress = destinationAddress, 56 | callback = directionsCallback 57 | ) 58 | } 59 | 60 | @Test 61 | fun testLatLngDirections() = runBlocking { 62 | instantiateMapfit(this@DirectionsTest.context) 63 | 64 | val originAddress = "111 Macdougal Street new york ny" 65 | val destinationAddress = "119 W 24th Street new york ny" 66 | 67 | Directions().route( 68 | originAddress = originAddress, 69 | destinationAddress = destinationAddress, 70 | callback = directionsCallback 71 | ) 72 | delay(1500) 73 | 74 | Mockito.verify(directionsCallback, Mockito.times(1)) 75 | .onSuccess(ArgumentMatchers.any(Route::class.java) ?: Route()) 76 | } 77 | 78 | @Test 79 | fun testErrorDirections() = runBlocking { 80 | instantiateMapfit(this@DirectionsTest.context) 81 | 82 | Directions().route( 83 | directionsType = DirectionsType.DRIVING, 84 | callback = directionsCallback 85 | ) 86 | 87 | delay(1500) 88 | 89 | Mockito.verify(directionsCallback, Mockito.times(1)) 90 | .onError( 91 | ArgumentMatchers.anyString(), 92 | Mockito.any(Exception::class.java) ?: Exception() 93 | ) 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/GeocoderTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | import com.mapfit.android.exceptions.MapfitConfigurationException 6 | import com.mapfit.android.geocoder.Geocoder 7 | import com.mapfit.android.geocoder.GeocoderCallback 8 | import com.mapfit.android.geocoder.model.Address 9 | import com.mapfit.android.geometry.LatLng 10 | import kotlinx.coroutines.experimental.delay 11 | import kotlinx.coroutines.experimental.runBlocking 12 | import org.junit.After 13 | import org.junit.Before 14 | import org.junit.Test 15 | import org.junit.runner.RunWith 16 | import org.mockito.ArgumentMatchers 17 | import org.mockito.Mock 18 | import org.mockito.Mockito 19 | import org.mockito.Mockito.times 20 | import org.mockito.Mockito.verify 21 | import org.mockito.MockitoAnnotations 22 | import java.lang.Exception 23 | 24 | 25 | /** 26 | * Created by dogangulcan on 1/22/18. 27 | */ 28 | @RunWith(AndroidJUnit4::class) 29 | class GeocoderTest { 30 | 31 | @Mock 32 | lateinit var geocoderCallback: GeocoderCallback 33 | 34 | private val context = InstrumentationRegistry.getContext() 35 | 36 | @Before 37 | fun init() { 38 | MockitoAnnotations.initMocks(this) 39 | } 40 | 41 | @After 42 | fun dispose() { 43 | Mapfit.dispose() 44 | } 45 | 46 | @Test(expected = MapfitConfigurationException::class) 47 | fun testMapfitConfiguration() { 48 | Geocoder().geocode( 49 | "119 w 24th st new york ny 10011", 50 | true, 51 | geocoderCallback 52 | ) 53 | } 54 | 55 | @Test(expected = MapfitConfigurationException::class) 56 | fun testMapfitConfiguration2() { 57 | Geocoder().reverseGeocode( 58 | LatLng(), 59 | true, 60 | geocoderCallback 61 | ) 62 | } 63 | 64 | @Test 65 | fun testGeocoderSuccessCallback() = runBlocking { 66 | instantiateMapfit(this@GeocoderTest.context) 67 | 68 | Geocoder().geocode( 69 | "119 w 24th st new york ny 10011", 70 | true, 71 | geocoderCallback 72 | ) 73 | 74 | delay(1000) 75 | verify(geocoderCallback, times(1)) 76 | .onSuccess( 77 | Mockito.any(List::class.java) as List
? ?: listOf() 78 | ) 79 | } 80 | 81 | @Test 82 | fun testGeocoderErrorCallback() { 83 | instantiateMapfit(this@GeocoderTest.context) 84 | 85 | Geocoder().geocode( 86 | "", 87 | true, 88 | geocoderCallback 89 | ) 90 | 91 | Thread.sleep(1000) 92 | verify(geocoderCallback, times(1)) 93 | .onError( 94 | ArgumentMatchers.anyString(), 95 | Mockito.any(Exception::class.java) ?: Exception() 96 | ) 97 | } 98 | 99 | @Test 100 | fun testReverseGeocoderSuccessCallback() { 101 | instantiateMapfit(this@GeocoderTest.context) 102 | 103 | Geocoder().reverseGeocode( 104 | LatLng(40.74405, -73.99324), 105 | true, 106 | geocoderCallback 107 | ) 108 | 109 | Thread.sleep(1000) 110 | verify(geocoderCallback, times(1)) 111 | .onSuccess( 112 | Mockito.any(List::class.java) as List
? ?: listOf() 113 | ) 114 | } 115 | 116 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/LayerTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.annotation.UiThreadTest 5 | import android.support.test.espresso.idling.CountingIdlingResource 6 | import android.support.test.runner.AndroidJUnit4 7 | import com.mapfit.android.annotations.Marker 8 | import com.mapfit.android.annotations.MarkerOptions 9 | import com.mapfit.android.geometry.LatLng 10 | import junit.framework.Assert 11 | import org.junit.After 12 | import org.junit.Before 13 | import org.junit.Test 14 | import org.junit.runner.RunWith 15 | import org.mockito.MockitoAnnotations 16 | 17 | /** 18 | * Unit tests for [Layer]. 19 | * 20 | * Created by dogangulcan on 1/5/18. 21 | */ 22 | @RunWith(AndroidJUnit4::class) 23 | class LayerTest { 24 | 25 | private lateinit var mapfitMap: MapfitMap 26 | 27 | private lateinit var mapfitMap2: MapfitMap 28 | 29 | private val mMockContext = InstrumentationRegistry.getContext() 30 | private val latLng = LatLng(40.693825, -73.998691) 31 | 32 | @Before 33 | @UiThreadTest 34 | fun init() { 35 | Mapfit.getInstance(mMockContext, mMockContext.getString(R.string.mapfit_debug_api_key)) 36 | MockitoAnnotations.initMocks(this) 37 | 38 | mapfitMap = MapView(mMockContext).getMap(MapTheme.MAPFIT_DAY.toString()) 39 | mapfitMap2 = MapView(mMockContext).getMap(MapTheme.MAPFIT_DAY.toString()) 40 | } 41 | 42 | @After 43 | fun dispose() { 44 | Mapfit.dispose() 45 | } 46 | 47 | @Test 48 | @UiThreadTest 49 | fun testLayerDefaults() { 50 | val layer = Layer() 51 | Assert.assertTrue(layer.visibility) 52 | } 53 | 54 | @Test 55 | @UiThreadTest 56 | fun testAddingMarkerToLayer() { 57 | val (marker, layer) = addLayerWithMarkerToMaps() 58 | layer.add(marker) 59 | Assert.assertEquals(2, marker.mapBindings.size) 60 | } 61 | 62 | @Test 63 | @UiThreadTest 64 | fun testAddingLayerToSecondMap() { 65 | val (marker, layer) = addLayerWithMarkerToMaps() 66 | Assert.assertEquals(2, marker.mapBindings.size) 67 | Assert.assertEquals(1, layer.annotations.size) 68 | } 69 | 70 | @Test 71 | @UiThreadTest 72 | fun testRemovingMarkerFromLayer() { 73 | val (marker, layer) = addLayerWithMarkerToMaps() 74 | layer.remove(marker) 75 | Assert.assertEquals(0, marker.mapBindings.size) 76 | Assert.assertEquals(0, layer.annotations.size) 77 | } 78 | 79 | @Test 80 | @UiThreadTest 81 | fun testRemovingMarker() { 82 | val (marker, layer) = addLayerWithMarkerToMaps() 83 | marker.remove() 84 | Assert.assertEquals(0, marker.mapBindings.size) 85 | Assert.assertEquals(0, layer.annotations.size) 86 | } 87 | 88 | 89 | @Test 90 | @UiThreadTest 91 | fun testRemovingLayerFromAMap() { 92 | val (marker, layer) = addLayerWithMarkerToMaps() 93 | Assert.assertEquals(2, marker.mapBindings.size) 94 | mapfitMap.removeLayer(layer) 95 | Assert.assertEquals(1, marker.mapBindings.size) 96 | } 97 | 98 | @Test 99 | @UiThreadTest 100 | fun testDisposingLayer() { 101 | val (marker, layer) = addLayerWithMarkerToMaps() 102 | layer.clear() 103 | Assert.assertEquals(0, marker.mapBindings.size) 104 | } 105 | 106 | private fun addLayerWithMarkerToMaps(): Pair { 107 | val marker = createMarker() 108 | val layer = Layer() 109 | layer.add(marker) 110 | mapfitMap.addLayer(layer) 111 | mapfitMap2.addLayer(layer) 112 | return Pair(marker, layer) 113 | } 114 | 115 | 116 | @Test 117 | @UiThreadTest 118 | fun testClear() { 119 | val latLng = LatLng(40.693825, -73.998691) 120 | val marker = mapfitMap.addMarker(MarkerOptions().position(latLng)) 121 | val layer = Layer() 122 | layer.add(marker) 123 | layer.add(marker) 124 | layer.add(marker) 125 | layer.add(marker) 126 | layer.clear() 127 | Assert.assertTrue(layer.annotations.size == 0) 128 | } 129 | 130 | private fun createMarker() = mapfitMap.addMarker(MarkerOptions().position(latLng)) 131 | 132 | 133 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/MapViewTestActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.os.Bundle 4 | import android.support.annotation.Nullable 5 | import android.support.test.espresso.idling.CountingIdlingResource 6 | import android.support.v7.app.AppCompatActivity 7 | import android.view.ViewGroup 8 | import android.widget.FrameLayout 9 | import com.mapfit.android.* 10 | 11 | /** 12 | * Dummy activity for testing [MapView]. 13 | * 14 | * Created by dogangulcan on 1/26/18. 15 | */ 16 | class MapViewTestActivity : AppCompatActivity() { 17 | 18 | val idlingResource = CountingIdlingResource("dummy_resource", true) 19 | lateinit var mapfitMap: MapfitMap 20 | lateinit var mapView: MapView 21 | 22 | override fun onCreate(@Nullable savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | instantiateMapfit(this) 25 | 26 | mapView = MapView(this) 27 | 28 | mapView.layoutParams = FrameLayout.LayoutParams( 29 | ViewGroup.LayoutParams.MATCH_PARENT, 30 | ViewGroup.LayoutParams.MATCH_PARENT 31 | ) 32 | mapView.id = R.id.mapView 33 | setContentView(mapView) 34 | } 35 | 36 | fun init() { 37 | idlingResource.increment() 38 | mapView.getMapAsync(onMapReadyCallback = object : OnMapReadyCallback { 39 | override fun onMapReady(mapfitMap: MapfitMap) { 40 | this@MapViewTestActivity.mapfitMap = mapfitMap 41 | idlingResource.decrement() 42 | } 43 | }) 44 | } 45 | 46 | override fun onDestroy() { 47 | super.onDestroy() 48 | Mapfit.dispose() 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/annotations/PolylineAnimationTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | import android.graphics.drawable.Animatable 4 | import android.support.test.annotation.UiThreadTest 5 | import android.support.test.espresso.IdlingRegistry 6 | import android.support.test.espresso.idling.CountingIdlingResource 7 | import android.support.test.rule.ActivityTestRule 8 | import android.support.test.runner.AndroidJUnit4 9 | import com.mapfit.android.* 10 | import com.mapfit.android.anim.AnimationListener 11 | import com.mapfit.android.anim.polyline.SnakeAnimation 12 | import com.mapfit.android.anim.polyline.SnakeAnimationOptions 13 | import com.mapfit.android.annotations.callback.OnPolylineClickListener 14 | import com.mapfit.android.geometry.LatLng 15 | import junit.framework.Assert 16 | import org.junit.After 17 | import org.junit.Before 18 | import org.junit.Rule 19 | import org.junit.Test 20 | import org.junit.runner.RunWith 21 | import org.mockito.Mock 22 | import org.mockito.MockitoAnnotations 23 | 24 | 25 | /** 26 | * Instrumentation tests for [Polyline] functionality. 27 | * 28 | * Created by dogangulcan on 1/17/18. 29 | */ 30 | @RunWith(AndroidJUnit4::class) 31 | class PolylineAnimationTest { 32 | 33 | @Mock 34 | private lateinit var polylineClickListener: OnPolylineClickListener 35 | 36 | private lateinit var mapfitMap: MapfitMap 37 | lateinit var mapView: MapView 38 | private var idlingResource = CountingIdlingResource("polyline_idling_resource") 39 | private val line by lazy { 40 | val list = mutableListOf().apply { 41 | add(LatLng(40.693825, -73.998691)) 42 | add(LatLng(40.6902223, -73.9770368)) 43 | add(LatLng(40.6930532, -73.9860919)) 44 | add(LatLng(40.7061326, -74.000769)) 45 | } 46 | list 47 | } 48 | 49 | @Rule 50 | @JvmField 51 | val activityRule: ActivityTestRule = ActivityTestRule( 52 | MapViewTestActivity::class.java, 53 | true, 54 | true 55 | ) 56 | 57 | @Before 58 | @UiThreadTest 59 | fun init() { 60 | MockitoAnnotations.initMocks(this) 61 | 62 | mapView = activityRule.activity.findViewById(R.id.mapView) 63 | mapfitMap = mapView.getMap(MapTheme.MAPFIT_DAY.toString()) 64 | mapfitMap.setOnPolylineClickListener(polylineClickListener) 65 | 66 | IdlingRegistry.getInstance().register(idlingResource) 67 | } 68 | 69 | @After 70 | @UiThreadTest 71 | fun dispose() { 72 | Mapfit.dispose() 73 | IdlingRegistry.getInstance().unregister(idlingResource) 74 | } 75 | 76 | 77 | @Test 78 | fun testSnakeAnimation() { 79 | val animationListener = object : AnimationListener { 80 | override fun onStart(animatable: Animatable) { 81 | idlingResource.decrement() 82 | 83 | } 84 | 85 | override fun onFinish(animatable: Animatable) { 86 | idlingResource.decrement() 87 | } 88 | } 89 | 90 | val polyline = mapfitMap.addPolyline( 91 | PolylineOptions() 92 | .points(line) 93 | .animation( 94 | SnakeAnimation( 95 | SnakeAnimationOptions() 96 | .duration(500) 97 | .animationListener(animationListener) 98 | ) 99 | ) 100 | ) 101 | 102 | mapfitMap.setLatLngBounds(polyline.getLatLngBounds(), 0.8f) 103 | mapfitMap.setZoom(16f) 104 | 105 | Assert.assertNotNull(polyline.animation) 106 | idlingResource.increment() 107 | idlingResource.increment() 108 | 109 | polyline.animation!!.start() 110 | 111 | suspendViaGLSurface() 112 | 113 | Assert.assertTrue(polyline.animation!!.finished) 114 | Assert.assertFalse(polyline.animation!!.running) 115 | Assert.assertFalse(polyline.animation!!.canceled) 116 | } 117 | } 118 | 119 | -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/map/MapListenersTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.map 2 | 3 | import android.support.test.annotation.UiThreadTest 4 | import android.support.test.espresso.Espresso.onView 5 | import android.support.test.espresso.IdlingRegistry 6 | import android.support.test.espresso.action.ViewActions.* 7 | import android.support.test.espresso.idling.CountingIdlingResource 8 | import android.support.test.espresso.matcher.ViewMatchers.withId 9 | import android.support.test.filters.LargeTest 10 | import android.support.test.rule.ActivityTestRule 11 | import android.support.test.runner.AndroidJUnit4 12 | import com.mapfit.android.* 13 | import com.mapfit.android.geometry.LatLng 14 | import kotlinx.coroutines.experimental.delay 15 | import kotlinx.coroutines.experimental.runBlocking 16 | import org.junit.After 17 | import org.junit.Before 18 | import org.junit.Rule 19 | import org.junit.Test 20 | import org.junit.runner.RunWith 21 | import org.mockito.Mock 22 | import org.mockito.Mockito 23 | import org.mockito.Mockito.* 24 | import org.mockito.MockitoAnnotations 25 | 26 | 27 | /** 28 | * Instrumentation tests for [MapView] functionality. 29 | * 30 | * Created by dogangulcan on 1/8/18. 31 | */ 32 | @RunWith(AndroidJUnit4::class) 33 | @LargeTest 34 | class MapListenersTest { 35 | 36 | private lateinit var mapView: MapView 37 | 38 | private lateinit var mapfitMap: MapfitMap 39 | 40 | @Mock 41 | private lateinit var onMapClickListener: OnMapClickListener 42 | 43 | @Mock 44 | private lateinit var onMapDoubleClickListener: OnMapDoubleClickListener 45 | 46 | @Mock 47 | private lateinit var onMapLongClickListener: OnMapLongClickListener 48 | 49 | @Mock 50 | private lateinit var onMapPanListener: OnMapPanListener 51 | 52 | @Mock 53 | private lateinit var onMapPinchListener: OnMapPinchListener 54 | 55 | @Rule 56 | @JvmField 57 | val activityRule: ActivityTestRule = ActivityTestRule( 58 | MapViewTestActivity::class.java, 59 | true, 60 | true 61 | ) 62 | 63 | @Before 64 | @UiThreadTest 65 | fun init() { 66 | MockitoAnnotations.initMocks(this) 67 | 68 | mapView = activityRule.activity.findViewById(R.id.mapView) 69 | mapfitMap = mapView.getMap(MapTheme.MAPFIT_DAY.toString()) 70 | mapfitMap.apply { 71 | setOnMapClickListener(onMapClickListener) 72 | setOnMapDoubleClickListener(onMapDoubleClickListener) 73 | setOnMapLongClickListener(onMapLongClickListener) 74 | setOnMapPanListener(onMapPanListener) 75 | setOnMapPinchListener(onMapPinchListener) 76 | } 77 | 78 | } 79 | 80 | @After 81 | fun cleanup() { 82 | Mapfit.dispose() 83 | } 84 | 85 | @Test 86 | fun testMapClickListener() = runBlocking { 87 | mapfitMap.setOnMapClickListener(onMapClickListener) 88 | 89 | onView(withId(R.id.glSurface)).perform(click()) 90 | delay(600) 91 | 92 | verify(onMapClickListener, times(1)) 93 | .onMapClicked(Mockito.any(LatLng::class.java) ?: LatLng()) 94 | } 95 | 96 | @Test 97 | fun testOnMapDoubleClickListener() = runBlocking { 98 | mapfitMap.setOnMapDoubleClickListener(onMapDoubleClickListener) 99 | 100 | onView(withId(R.id.glSurface)).perform(doubleClick()) 101 | delay(600) 102 | 103 | verify(onMapDoubleClickListener, times(1)) 104 | .onMapDoubleClicked(Mockito.any(LatLng::class.java) ?: LatLng()) 105 | } 106 | 107 | @Test 108 | fun testOnMapLongClickListener() = runBlocking { 109 | mapfitMap.setOnMapLongClickListener(onMapLongClickListener) 110 | 111 | onView(withId(R.id.glSurface)).perform(longClick()) 112 | delay(600) 113 | 114 | verify(onMapLongClickListener, times(1)) 115 | .onMapLongClicked(Mockito.any(LatLng::class.java) ?: LatLng()) 116 | } 117 | 118 | @Test 119 | fun testOnMapPanListener() = runBlocking { 120 | mapfitMap.setOnMapPanListener(onMapPanListener) 121 | 122 | onView(withId(R.id.glSurface)).perform(swipeDown()) 123 | delay(600) 124 | 125 | verify(onMapPanListener, atLeastOnce()).onMapPan() 126 | } 127 | 128 | @Test 129 | fun testOnMapPinchListener() = runBlocking { 130 | mapfitMap.setOnMapPinchListener(onMapPinchListener) 131 | 132 | onView(withId(R.id.glSurface)).perform(pinchIn()) 133 | delay(600) 134 | 135 | verify(onMapPinchListener, atLeastOnce()).onMapPinch() 136 | 137 | onView(withId(R.id.glSurface)).perform(pinchOut()) 138 | delay(600) 139 | 140 | verify(onMapPinchListener, atLeastOnce()).onMapPinch() 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /android-sdk/src/androidTest/java/com/mapfit/android/map/MapViewUiControlsTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.map 2 | 3 | import android.support.test.annotation.UiThreadTest 4 | import android.support.test.rule.ActivityTestRule 5 | import android.support.test.rule.GrantPermissionRule 6 | import android.support.test.runner.AndroidJUnit4 7 | import android.view.View 8 | import com.mapfit.android.* 9 | import kotlinx.coroutines.experimental.runBlocking 10 | import org.junit.* 11 | import org.junit.runner.RunWith 12 | import org.mockito.MockitoAnnotations 13 | 14 | 15 | /** 16 | * Instrumentation tests for UI controls. 17 | * 18 | * Created by dogangulcan on 1/8/18. 19 | */ 20 | @RunWith(AndroidJUnit4::class) 21 | class MapViewUiControlsTest { 22 | 23 | private lateinit var mapView: MapView 24 | private lateinit var mapfitMap: MapfitMap 25 | 26 | @Rule 27 | @JvmField 28 | val activityRule: ActivityTestRule = ActivityTestRule( 29 | MapViewTestActivity::class.java 30 | ) 31 | 32 | @Rule 33 | @JvmField 34 | val grantPermissionRule: GrantPermissionRule = 35 | GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION) 36 | 37 | @Before 38 | @UiThreadTest 39 | fun init() { 40 | MockitoAnnotations.initMocks(this) 41 | 42 | mapView = activityRule.activity.findViewById(R.id.mapView) 43 | mapfitMap = mapView.getMap(MapTheme.MAPFIT_DAY.toString()) 44 | } 45 | 46 | @After 47 | @UiThreadTest 48 | fun cleanup() { 49 | Mapfit.dispose() 50 | } 51 | 52 | @Test 53 | @UiThreadTest 54 | fun testDefaultValues() = runBlocking { 55 | Assert.assertEquals(View.GONE, mapView.zoomControlsView.visibility) 56 | Assert.assertEquals(View.GONE, mapView.btnRecenter.visibility) 57 | Assert.assertEquals(View.GONE, mapView.btnCompass.visibility) 58 | Assert.assertEquals(View.GONE, mapView.btnUserLocation.visibility) 59 | Assert.assertEquals(View.VISIBLE, mapView.attributionImage.visibility) 60 | } 61 | 62 | @Test 63 | @UiThreadTest 64 | fun testAttribution() { 65 | Assert.assertEquals(View.VISIBLE, mapView.attributionImage.visibility) 66 | } 67 | 68 | @Test 69 | @UiThreadTest 70 | fun testCompassButton() { 71 | mapfitMap.getMapOptions().isCompassButtonVisible = true 72 | Assert.assertEquals(View.VISIBLE, mapView.btnCompass.visibility) 73 | } 74 | 75 | @Test 76 | @UiThreadTest 77 | fun testZoomControls() { 78 | mapfitMap.getMapOptions().isZoomControlVisible = true 79 | Assert.assertEquals(View.VISIBLE, mapView.zoomControlsView.visibility) 80 | } 81 | 82 | @Test 83 | @UiThreadTest 84 | fun testRecenterButton() { 85 | mapfitMap.getMapOptions().isRecenterButtonVisible = true 86 | Assert.assertEquals(View.VISIBLE, mapView.btnRecenter.visibility) 87 | } 88 | 89 | @Test 90 | @UiThreadTest 91 | fun testUserLocationButton() { 92 | mapfitMap.getMapOptions().isUserLocationButtonVisible = true 93 | Assert.assertEquals(View.VISIBLE, mapView.btnUserLocation.visibility) 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /android-sdk/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android-sdk/src/main/cpp/androidPlatform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "platform.h" 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace Tangram { 15 | 16 | struct LabelPickResult; 17 | struct FeaturePickResult; 18 | struct MarkerPickResult; 19 | class Map; 20 | struct SceneUpdate; 21 | struct SceneError; 22 | using SceneID = int32_t; 23 | 24 | void featurePickCallback(jobject listener, const FeaturePickResult* featurePickResult); 25 | void markerPickCallback(jobject listener, jobject tangramInstance, const MarkerPickResult* markerPickResult); 26 | void labelPickCallback(jobject listener, const LabelPickResult* labelPickResult); 27 | 28 | std::string stringFromJString(JNIEnv* jniEnv, jstring string); 29 | jstring jstringFromString(JNIEnv* jniEnv, const std::string& string); 30 | 31 | class AndroidPlatform : public Platform { 32 | 33 | public: 34 | 35 | AndroidPlatform(JNIEnv* _jniEnv, jobject _assetManager, jobject _tangramInstance); 36 | void dispose(JNIEnv* _jniEnv); 37 | void requestRender() const override; 38 | void setContinuousRendering(bool _isContinuous) override; 39 | FontSourceHandle systemFont(const std::string& _name, const std::string& _weight, const std::string& _face) const override; 40 | std::vector systemFontFallbacksHandle() const override; 41 | UrlRequestHandle startUrlRequest(Url _url, UrlCallback _callback) override; 42 | void cancelUrlRequest(UrlRequestHandle _request) override; 43 | void sceneReadyCallback(SceneID id, const SceneError* error); 44 | 45 | void onUrlComplete(JNIEnv* jniEnv, jlong jRequestHandle, jbyteArray jBytes, jstring jError); 46 | 47 | static void bindJniEnvToThread(JNIEnv* jniEnv); 48 | static void setupJniEnv(JNIEnv* _jniEnv); 49 | 50 | private: 51 | 52 | std::vector bytesFromFile(const Url& _url) const; 53 | bool bytesFromAssetManager(const char* _path, std::function _allocator) const; 54 | std::string fontPath(const std::string& _family, const std::string& _weight, const std::string& _style) const; 55 | std::string fontFallbackPath(int _importance, int _weightHint) const; 56 | 57 | jobject m_tangramInstance; 58 | AAssetManager* m_assetManager; 59 | 60 | std::atomic_uint_fast64_t m_urlRequestCount; 61 | 62 | // m_callbackMutex should be locked any time m_callbacks is accessed. 63 | std::mutex m_callbackMutex; 64 | std::unordered_map m_callbacks; 65 | 66 | }; 67 | 68 | } // namespace Tangram 69 | -------------------------------------------------------------------------------- /android-sdk/src/main/cpp/sqlite3ndk.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is Krystian Bigaj code. 15 | * 16 | * The Initial Developer of the Original Code is 17 | * Krystian Bigaj (krystian.bigaj@gmail.com). 18 | * Portions created by the Initial Developer are Copyright (C) 2011 19 | * the Initial Developer. All Rights Reserved. 20 | * 21 | * Contributor(s): 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #ifndef _SQLITE3_NDK_H_ 38 | #define _SQLITE3_NDK_H_ 39 | 40 | #include 41 | #include 42 | 43 | #ifndef SQLITE_NDK_VFS_NAME 44 | // Default name for VFS 45 | #define SQLITE_NDK_VFS_NAME "ndk-asset" 46 | #endif 47 | 48 | #ifndef SQLITE_NDK_VFS_MAKE_DEFAULT 49 | // Default sqlite3_ndk_init parameter 50 | #define SQLITE_NDK_VFS_MAKE_DEFAULT 0 51 | #endif 52 | 53 | // Default sqlite3_ndk_init parameter 54 | #define SQLITE_NDK_VFS_PARENT_VFS NULL 55 | 56 | #ifndef SQLITE_NDK_VFS_MAX_PATH 57 | // Maximum path name for database files 58 | #define SQLITE_NDK_VFS_MAX_PATH 512 59 | #endif 60 | 61 | /* 62 | * This function registers VFS into SQLite. 63 | * It should be called only once (before SQLite-NDK usage). 64 | * 65 | * Params: 66 | * - assetMgr - pointer to AAssetManager. In most cases it will be: 67 | * app->activity->assetManager (see example below). 68 | * This parameter is required 69 | * - vfsName - name of VFS that can be used in sqlite3_open_v2 70 | * as 4th parameter (http://www.sqlite.org/c3ref/open.html) 71 | * or in URI filename (http://www.sqlite.org/uri.html). 72 | * If NULL then default name "ndk-asset" is used (SQLITE_NDK_VFS_NAME) 73 | * - makeDflt - flag used to register SQLite-NDK as a default VFS. 74 | * See: sqlite3_vfs_register at http://www.sqlite.org/c3ref/vfs_find.html 75 | * Disabled by default (SQLITE_NDK_VFS_MAKE_DEFAULT) 76 | * - osVfs - name of VFS that will used only to redirect few sqlite calls. 77 | * If NULL passed, then default VFS will be used (SQLITE_NDK_VFS_PARENT_VFS) 78 | * 79 | * Example: 80 | * void android_main(struct android_app* app) 81 | * { 82 | * sqlite3_ndk_init(app->activity->assetManager); 83 | * ... 84 | * if (sqlite3_open_v2("data.sqlite3", &db, SQLITE_OPEN_READONLY, 85 | * SQLITE_NDK_VFS_NAME) == SQLITE_OK) 86 | * { 87 | * ... 88 | */ 89 | int sqlite3_ndk_init(AAssetManager* assetMgr, 90 | const char* vfsName = SQLITE_NDK_VFS_NAME, 91 | int makeDflt = SQLITE_NDK_VFS_MAKE_DEFAULT, 92 | const char *osVfs = SQLITE_NDK_VFS_PARENT_VFS); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/DirectionsOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.annotations.Polyline 4 | import com.mapfit.android.annotations.PolylineOptions 5 | import com.mapfit.android.directions.Directions 6 | import com.mapfit.android.directions.DirectionsCallback 7 | import com.mapfit.android.directions.DirectionsType 8 | import com.mapfit.android.directions.model.Route 9 | import com.mapfit.android.geometry.LatLng 10 | import com.mapfit.android.utils.decodePolyline 11 | 12 | /** 13 | * Used to obtain route and draw directions on map from an origin to a destination. 14 | * 15 | * Created by dogangulcan on 1/4/18. 16 | */ 17 | class DirectionsOptions internal constructor(private val mapController: MapController) { 18 | 19 | private var originLocation = LatLng() 20 | private var destinationLocation = LatLng() 21 | private var originLocationString = "" 22 | private var destinationLocationString = "" 23 | private var type: DirectionsType = DirectionsType.DRIVING 24 | 25 | internal var routeDrawn = false 26 | 27 | /** 28 | * Sets origin for the directions to the given [LatLng] coordinates. 29 | * 30 | * @param latLng coordinates for origin 31 | */ 32 | fun setOrigin(latLng: LatLng): DirectionsOptions { 33 | this.originLocation = latLng 34 | return this 35 | } 36 | 37 | /** 38 | * Sets destination for the directions to the given [LatLng] coordinates. 39 | * 40 | * @param latLng coordinates for destination 41 | */ 42 | fun setDestination(latLng: LatLng): DirectionsOptions { 43 | this.destinationLocation = latLng 44 | return this 45 | } 46 | 47 | /** 48 | * Sets origin for the directions to the given street address. 49 | * 50 | * @param address street address for origin 51 | */ 52 | fun setOrigin(address: String): DirectionsOptions { 53 | this.originLocationString = address 54 | return this 55 | } 56 | 57 | /** 58 | * Sets destination for the directions to the given street address. 59 | * 60 | * @param address street address for destination 61 | */ 62 | fun setDestination(address: String): DirectionsOptions { 63 | this.destinationLocationString = address 64 | return this 65 | } 66 | 67 | /** 68 | * Sets type for the directions. See [DirectionsType]. 69 | * 70 | * @param type of directions 71 | */ 72 | fun setType(type: DirectionsType): DirectionsOptions { 73 | this.type = type 74 | return this 75 | } 76 | 77 | /** 78 | * Returns the current [DirectionsType]. 79 | * @return directions type 80 | */ 81 | fun getType() = type 82 | 83 | /** 84 | * Draws the route as polyline on the map and returns the route details to the given 85 | * [RouteDrawCallback]. 86 | * 87 | * @param callback will be called when the route is drawn on the map as polyline 88 | */ 89 | fun showDirections(callback: RouteDrawCallback) { 90 | 91 | val directionsCallback = object : DirectionsCallback { 92 | override fun onSuccess(route: Route) { 93 | val legs = drawRoute(route) 94 | callback.onRouteDrawn(route, legs) 95 | } 96 | 97 | override fun onError(message: String, e: Exception) { 98 | callback.onError("", e) 99 | } 100 | } 101 | 102 | Directions().route( 103 | originLocation = originLocation, 104 | originAddress = originLocationString, 105 | destinationLocation = destinationLocation, 106 | destinationAddress = destinationLocationString, 107 | directionsType = type, 108 | callback = directionsCallback 109 | ) 110 | } 111 | 112 | private fun drawRoute(route: Route): List { 113 | val legs = mutableListOf() 114 | route.trip.legs.forEach { 115 | val line = decodePolyline(it.shape) 116 | val polyline = mapController.addPolyline(PolylineOptions().points(line)) 117 | legs.add(polyline) 118 | routeDrawn = true 119 | } 120 | return legs 121 | } 122 | 123 | /** 124 | * Callback to be invoked when the route is drawn or there is an error. 125 | */ 126 | interface RouteDrawCallback { 127 | 128 | fun onRouteDrawn(route: Route, legs: List) 129 | 130 | /** 131 | * Called when route is not drawn and an error has occurred. 132 | */ 133 | fun onError(message: String, e: Exception) 134 | 135 | } 136 | 137 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/Layer.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.annotations.Annotation 4 | import com.mapfit.android.annotations.Marker 5 | import com.mapfit.android.annotations.Polygon 6 | import com.mapfit.android.annotations.Polyline 7 | import com.mapfit.android.geometry.LatLngBounds 8 | 9 | /** 10 | * Layer structure is to re-use [Annotation]s and have them synchronised across maps. 11 | * 12 | * Created by dogangulcan on 12/21/17. 13 | */ 14 | class Layer { 15 | 16 | val annotations = mutableListOf() 17 | 18 | private val maps = mutableListOf() 19 | 20 | var visibility = true 21 | set(value) { 22 | if (field != value) { 23 | annotations.forEach { it.visibility = value } 24 | field = value 25 | } 26 | } 27 | 28 | /** 29 | * Adds the input annotation to the layer. 30 | * 31 | * @param annotation e.g. marker, polyline, polygon, etc. 32 | */ 33 | fun add(annotation: Annotation) { 34 | annotations.add(annotation) 35 | annotation.bindToLayer(this) 36 | 37 | maps.forEach { mapController -> 38 | annotation.addToMap(mapController) 39 | } 40 | } 41 | 42 | internal fun addMap(mapController: MapController) { 43 | maps.takeIf { !maps.contains(mapController) }?.add(mapController) 44 | annotations.forEach { 45 | it.addToMap(mapController) 46 | } 47 | } 48 | 49 | /** 50 | * Removes the input annotation(s) from the layer. 51 | */ 52 | fun remove(vararg annotation: Annotation) { 53 | annotation.forEach { 54 | it.remove(maps) 55 | it.subAnnotation?.remove(maps) 56 | annotations.remove(it) 57 | it.layers.remove(this@Layer) 58 | } 59 | } 60 | 61 | /** 62 | * Returns the bounding coordinates for the layer. 63 | */ 64 | fun getLatLngBounds(): LatLngBounds { 65 | val boundsBuilder = LatLngBounds.Builder() 66 | 67 | annotations.forEach { it -> 68 | addBounds(it, boundsBuilder) 69 | } 70 | 71 | return boundsBuilder.build() 72 | } 73 | 74 | private fun addBounds( 75 | it: Annotation, 76 | boundsBuilder: LatLngBounds.Builder 77 | ) { 78 | when (it) { 79 | is Marker -> boundsBuilder.include(it.position) 80 | is Polyline -> it.points.forEach { boundsBuilder.include(it) } 81 | is Polygon -> it.points.forEach { it.forEach { boundsBuilder.include(it) } } 82 | } 83 | 84 | it.subAnnotation?.let { addBounds(it, boundsBuilder) } 85 | } 86 | 87 | /** 88 | * Removes every annotation from the layer and the maps the layer is added to. 89 | */ 90 | fun clear() { 91 | annotations.forEach { it.remove(maps) } 92 | annotations.clear() 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/MapData.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.util.Log 4 | import com.mapfit.android.annotations.Marker 5 | import com.mapfit.android.annotations.Polygon 6 | import com.mapfit.android.annotations.Polyline 7 | 8 | /** 9 | * `MapData` is a named collection of drawable map features. 10 | */ 11 | class MapData 12 | /** 13 | * For package-internal use only; create a new `MapData` 14 | * 15 | * @param name The name of the associated data source 16 | * @param pointer The markerId to the native data source, encoded as a long 17 | * @param map The `MapController` associated with this data source 18 | */ 19 | internal constructor(var name: String, var id: Long, private var map: MapController?) { 20 | 21 | /** 22 | * Remove this `MapData` from the map it is currently associated with. Using this object 23 | * after `remove` is called will cause an exception to be thrown. `remove` is called 24 | * on every `MapData` associated with a map when its `MapController` is destroyed. 25 | */ 26 | fun remove() { 27 | map!!.removeDataLayer(this) 28 | id = 0 29 | map = null 30 | } 31 | 32 | /** 33 | * Add a point feature to this collection. 34 | * the scene file used by the map; may be null. 35 | * 36 | * @return This object, for chaining. 37 | */ 38 | fun addPoint(marker: Marker): MapData { 39 | val coordinates = DoubleArray(2) 40 | coordinates[0] = marker.position.lng 41 | coordinates[1] = marker.position.lat 42 | 43 | map!!.addFeature( 44 | id, 45 | coordinates, 46 | null, 47 | null 48 | ) 49 | 50 | return this 51 | } 52 | 53 | fun addPolyline(polyline: Polyline): MapData { 54 | 55 | // skip drawing if polyline has animation 56 | val coordinates = if (polyline.animation != null && 57 | !polyline.animation!!.isRunning && 58 | !polyline.animation!!.finished 59 | ) { 60 | doubleArrayOf() 61 | } else { 62 | polyline.coordinates 63 | } 64 | 65 | map?.let { 66 | it.addFeature( 67 | id, 68 | coordinates, 69 | null, 70 | polyline.getProperties(polyline.getIdForMap(it).toString()) 71 | ) 72 | } 73 | return this 74 | } 75 | 76 | /** 77 | * Add a polygon feature to this collection. 78 | * 79 | * @param polygon A list of rings describing the shape of the feature. Each 80 | * ring is a list of coordinates in which the first point is the same as the last point. The 81 | * first ring is taken as the "exterior" of the polygon and rings with opposite winding are 82 | * considered "holes". 83 | * @return This object, for chaining. 84 | */ 85 | fun addPolygon(polygon: Polygon): MapData { 86 | map?.let { 87 | it.addFeature( 88 | id, 89 | polygon.coordinates, 90 | polygon.rings, 91 | polygon.getProperties(polygon.getIdForMap(it).toString()) 92 | ) 93 | } 94 | return this 95 | } 96 | 97 | /** 98 | * Add features described in a GeoJSON string to this collection. 99 | * 100 | * @param data A string containing a [GeoJSON](http://geojson.org/) FeatureCollection 101 | * @return This object, for chaining. 102 | */ 103 | fun addGeoJson(data: String): MapData { 104 | map!!.addGeoJson(id, data) 105 | return this 106 | } 107 | 108 | 109 | /** 110 | * Remove all features from this collection. 111 | * 112 | * @return This object, for chaining. 113 | */ 114 | fun clear(): MapData { 115 | map!!.clearTileSource(id) 116 | return this 117 | } 118 | 119 | 120 | } 121 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/MapTheme.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | 4 | /** 5 | * Built in Mapfit map themes. 6 | */ 7 | enum class MapTheme(private val scenePath: String) { 8 | MAPFIT_DAY("https://cdn.mapfit.com/v3-0/themes/mapfit-day.yaml"), 9 | MAPFIT_NIGHT("https://cdn.mapfit.com/v3-0/themes/mapfit-night.yaml"), 10 | MAPFIT_GRAYSCALE("https://cdn.mapfit.com/v3-0/themes/mapfit-grayscale.yaml"); 11 | 12 | override fun toString(): String { 13 | return scenePath 14 | } 15 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/Mapfit.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import com.mapfit.android.exceptions.MapfitConfigurationException 6 | import org.jetbrains.annotations.TestOnly 7 | 8 | 9 | /** 10 | * Mapfit class is to initialize Mapfit Android SDK. 11 | * 12 | * Created by dogangulcan on 12/18/17. 13 | */ 14 | class Mapfit private constructor(private val context: Context?, apiKey: String) { 15 | 16 | companion object { 17 | 18 | internal const val TAG = "Mapfit" 19 | 20 | @SuppressLint("StaticFieldLeak") 21 | @Volatile 22 | private var mapfitInstance: Mapfit? = null 23 | 24 | @Volatile 25 | private var appContext: Context? = null 26 | 27 | private lateinit var MAPFIT_API_KEY: String 28 | 29 | @JvmStatic 30 | fun getInstance(context: Context? = null, apiKey: String): Mapfit { 31 | MAPFIT_API_KEY = apiKey 32 | appContext = context 33 | return synchronized(this) { 34 | if (mapfitInstance == null) { 35 | mapfitInstance = Mapfit(context, apiKey) 36 | } 37 | mapfitInstance as Mapfit 38 | } 39 | } 40 | 41 | /** 42 | * Returns Mapfit API key. 43 | */ 44 | @JvmStatic 45 | fun getApiKey(): String { 46 | validateMapfit() 47 | validateApiKey() 48 | return MAPFIT_API_KEY 49 | } 50 | 51 | fun getContext(): Context? = appContext 52 | 53 | private fun validateMapfit() { 54 | if (mapfitInstance == null) { 55 | throw MapfitConfigurationException() 56 | } 57 | } 58 | 59 | private fun validateApiKey() { 60 | val apiKey = MAPFIT_API_KEY 61 | if (apiKey.isNullOrBlank()) { 62 | throw MapfitConfigurationException() 63 | } 64 | } 65 | 66 | @TestOnly 67 | internal fun dispose() { 68 | MAPFIT_API_KEY = "" 69 | } 70 | 71 | 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | 5 | /** 6 | * Interface to listen map click events. 7 | * 8 | * Created by dogangulcan on 1/4/18. 9 | */ 10 | interface OnMapClickListener { 11 | 12 | fun onMapClicked(latLng: LatLng) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapDoubleClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | 5 | /** 6 | * Interface to listen map double click events. 7 | * 8 | * Created by dogangulcan on 1/4/18. 9 | */ 10 | interface OnMapDoubleClickListener{ 11 | 12 | fun onMapDoubleClicked(latLng: LatLng) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapLongClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | 5 | /** 6 | * Interface to listen map long click events. 7 | * 8 | * Created by dogangulcan on 1/4/18. 9 | */ 10 | interface OnMapLongClickListener { 11 | 12 | fun onMapLongClicked(latLng: LatLng) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapPanListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.support.annotation.UiThread 4 | 5 | /** 6 | * Interface to listen map pan events. 7 | * 8 | * Created by dogangulcan on 1/4/18. 9 | */ 10 | interface OnMapPanListener { 11 | 12 | /** 13 | * Called when the map is panned. This can be called each frame update and should not perform 14 | * heavy calculations. 15 | */ 16 | @UiThread 17 | fun onMapPan() 18 | 19 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapPinchListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.support.annotation.UiThread 4 | 5 | /** 6 | * Interface to listen map pinch events. 7 | * 8 | * Created by dogangulcan on 1/4/18. 9 | */ 10 | interface OnMapPinchListener { 11 | 12 | /** 13 | * Called when the map is pinched. This can be called each frame update and should not perform 14 | * heavy calculations. 15 | */ 16 | @UiThread 17 | fun onMapPinch() 18 | 19 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapReadyCallback.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import org.jetbrains.annotations.NotNull 4 | 5 | /** 6 | * Callback for obtaining [MapfitMap] instance to manipulate the map. 7 | * 8 | * Created by dogangulcan on 12/18/17. 9 | */ 10 | interface OnMapReadyCallback { 11 | 12 | fun onMapReady(@NotNull mapfitMap: MapfitMap) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/OnMapThemeLoadListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | /** 4 | * Callback to listen map scene load events after changing map theme or updating the scene values. 5 | * 6 | * Created by dogangulcan on 3/7/18. 7 | */ 8 | interface OnMapThemeLoadListener { 9 | 10 | fun onLoaded() 11 | 12 | fun onError() 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/Animation.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim 2 | 3 | import android.graphics.drawable.Animatable 4 | 5 | abstract class Animation : Animatable { 6 | 7 | var running = false 8 | var paused = false 9 | var canceled = false 10 | var finished = false 11 | 12 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/AnimationListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim 2 | 3 | import android.graphics.drawable.Animatable 4 | 5 | interface AnimationListener { 6 | 7 | /** 8 | * Invoked on animation start. 9 | */ 10 | fun onStart(animatable: Animatable) 11 | 12 | 13 | /** 14 | * Invoked on animation end. 15 | */ 16 | fun onFinish(animatable: Animatable) 17 | 18 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/AnimationOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim 2 | 3 | import android.view.animation.AccelerateDecelerateInterpolator 4 | import android.view.animation.Interpolator 5 | 6 | @Suppress("UNCHECKED_CAST") 7 | abstract class AnimationOptions { 8 | 9 | internal var duration: Long = 2000L 10 | internal var interpolator: Interpolator = AccelerateDecelerateInterpolator() 11 | internal var listener: AnimationListener? = null 12 | 13 | /** 14 | * Sets the duration of the animation. 15 | * 16 | * @param duration in milliseconds 17 | */ 18 | fun duration(duration: Long): T { 19 | this.duration = duration 20 | return this as T 21 | } 22 | 23 | /** 24 | * Sets the interpolator for the animation. 25 | * 26 | * @param interpolator 27 | */ 28 | fun interpolator(interpolator: Interpolator): T { 29 | this.interpolator = interpolator 30 | return this as T 31 | } 32 | 33 | /** 34 | * Sets [AnimationListener] for animation events. 35 | * 36 | * @param listener 37 | */ 38 | fun animationListener(listener: AnimationListener): T { 39 | this.listener = listener 40 | return this as T 41 | } 42 | 43 | 44 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/RouteEvaluator.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim 2 | 3 | import android.animation.TypeEvaluator 4 | import com.mapfit.android.geometry.LatLng 5 | 6 | 7 | class RouteEvaluator : TypeEvaluator { 8 | override fun evaluate(t: Float, startPoint: LatLng, endPoint: LatLng): LatLng { 9 | val lat = startPoint.lat + t * (endPoint.lat - startPoint.lat) 10 | val lng = startPoint.lng + t * (endPoint.lng - startPoint.lng) 11 | return LatLng(lat, lng) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/polyline/PolylineAnimation.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim.polyline 2 | 3 | import com.mapfit.android.anim.Animation 4 | import com.mapfit.android.annotations.Polyline 5 | 6 | abstract class PolylineAnimation : Animation() { 7 | 8 | internal var polyline: Polyline? = null 9 | 10 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/anim/polyline/SnakeAnimationOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.anim.polyline 2 | 3 | import com.mapfit.android.anim.AnimationOptions 4 | 5 | class SnakeAnimationOptions : AnimationOptions() -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/Anchor.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Anchor for Annotations. Since top-left of the screen is (0,0), upper bound of the screen is 5 | * considered as BOTTOM. 6 | * 7 | * Created by dogangulcan on 3/2/18. 8 | */ 9 | enum class Anchor(private val anchor: String) { 10 | 11 | TOP("top"), 12 | TOP_LEFT("top-left"), 13 | TOP_RIGHT("top-right"), 14 | LEFT("left"), 15 | RIGHT("right"), 16 | CENTER("center"), 17 | BOTTOM("bottom"), 18 | BOTTOM_LEFT("bottom-left"), 19 | BOTTOM_RIGHT("bottom-right"); 20 | 21 | internal fun getAnchor(): String { 22 | return anchor 23 | } 24 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/Annotation.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | import android.support.annotation.RestrictTo 4 | import com.mapfit.android.Layer 5 | import com.mapfit.android.MapController 6 | import com.mapfit.android.geometry.LatLngBounds 7 | import com.mapfit.android.utils.generateUniqueId 8 | import java.util.* 9 | 10 | /** 11 | * Base class for [Marker], [Polyline] and [Polygon]. 12 | * 13 | * Created by dogangulcan on 12/22/17. 14 | */ 15 | abstract class Annotation( 16 | id: Long, 17 | mapController: MapController 18 | ) { 19 | 20 | internal val mapBindings = HashMap() 21 | internal val layers = mutableListOf() 22 | var data: Any? = null 23 | 24 | var visibility: Boolean = true 25 | set(value) { 26 | if (field != value) { 27 | mapBindings.forEach { it -> 28 | it.key.changeAnnotationVisibility(it.value, value) 29 | } 30 | subAnnotation?.visibility = value 31 | field = value 32 | } 33 | } 34 | 35 | internal var subAnnotation: Annotation? = null 36 | 37 | /** 38 | * Annotation's unique identifier. 39 | */ 40 | val id: Long by lazy { generateUniqueId() } 41 | 42 | init { 43 | mapBindings[mapController] = id 44 | } 45 | 46 | internal fun addToMap(mapController: MapController) { 47 | if (!mapBindings.containsKey(mapController)) { 48 | val newId = mapController.addAnnotation(this) 49 | mapBindings[mapController] = newId 50 | initAnnotation(mapController, newId) 51 | 52 | subAnnotation?.addToMap(mapController) 53 | } 54 | } 55 | 56 | internal fun bindToLayer(layer: Layer) { 57 | if (!layers.contains(layer)) { 58 | layers.add(layer) 59 | subAnnotation?.bindToLayer(layer) 60 | } 61 | } 62 | 63 | /** 64 | * Do not use this method. It is for internal usage. 65 | */ 66 | fun getIdForMap(mapController: MapController): Long? = mapBindings[mapController] 67 | 68 | /** 69 | * Do not use this method. It is for internal usage. 70 | */ 71 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 72 | abstract fun initAnnotation(mapController: MapController, id: Long) 73 | 74 | abstract fun getLatLngBounds(): LatLngBounds 75 | 76 | abstract fun remove() 77 | 78 | internal abstract fun remove(mapController: MapController) 79 | 80 | internal fun remove(maps: List) { 81 | mapBindings.filter { maps.contains(it.key) } 82 | .forEach { 83 | when (this@Annotation) { 84 | is Marker -> it.key.removeMarker(it.value) 85 | is Polygon -> it.key.removePolygon(it.value) 86 | is Polyline -> it.key.removePolyline(it.value) 87 | } 88 | mapBindings.remove(it.key) 89 | } 90 | } 91 | 92 | 93 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/Building.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | import android.graphics.PointF 4 | import com.mapfit.android.geometry.LatLng 5 | 6 | internal data class Building @JvmOverloads constructor( 7 | var position: PointF = PointF(), 8 | var latLng: LatLng = LatLng(), 9 | var id: Long = 0L, 10 | var rootId: Long = 0L 11 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/BuildingOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | 4 | class BuildingOptions : PolyPointAnnotationOptions() { 5 | 6 | internal var fillColor: String = "" 7 | 8 | init { 9 | drawOrder = 600 10 | } 11 | 12 | /** 13 | * Sets the fill color of the polygon. 14 | * 15 | * @param color as hex like "#ff00ff" 16 | */ 17 | fun fillColor(color: String): BuildingOptions { 18 | this.fillColor = color 19 | return this 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/CapType.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Enumerates the shape types for the end of line shapes. 5 | */ 6 | enum class CapType(private val value: String) { 7 | BOUND("0"), 8 | SQUARE("2"), 9 | ROUND("6"); 10 | 11 | internal fun getValue() = value 12 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/JoinType.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Represents the shape types for joints in multi-segment lines 5 | */ 6 | enum class JoinType(private val value: String) { 7 | MITER("0"), 8 | BEVEL("1"), 9 | ROUND("5"); 10 | 11 | internal fun getValue() = value 12 | } 13 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/MapfitMarker.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Default Mapfit marker icons. 5 | * 6 | * Created by dogangulcan on 12/27/17. 7 | */ 8 | enum class MapfitMarker(private val iconUrl: String) { 9 | 10 | DEFAULT("default"), 11 | ACTIVE("active"), 12 | AIRPORT("airport"), 13 | ARTS("arts"), 14 | AUTO("auto"), 15 | FINANCE("finance"), 16 | COMMERCIAL("commercial"), 17 | CAFE("cafe"), 18 | CONFERENCE("conference"), 19 | SPORTS("sports"), 20 | EDUCATION("education"), 21 | MARKET("market"), 22 | COOKING("cooking"), 23 | GAS("gas"), 24 | HOMEGARDEN("homegarden"), 25 | HOSPITAL("hospital"), 26 | HOTEL("hotel"), 27 | LAW("law"), 28 | MEDICAL("medical"), 29 | BAR("bar"), 30 | PARK("park"), 31 | PHARMACY("pharmacy"), 32 | COMMUNITY("community"), 33 | RELIGION("religion"), 34 | RESTAURANT("restaurant"), 35 | SHOPPING("shopping"); 36 | 37 | internal fun getUrl() = 38 | "http://cdn.mapfit.com/v2-4/assets/images/markers/pngs/lighttheme/$iconUrl.png" 39 | 40 | } 41 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/OnAnnotationClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Interface to listen [Annotation] click events. 5 | * 6 | * Created by dogangulcan on 2/12/18. 7 | */ 8 | internal interface OnAnnotationClickListener { 9 | 10 | fun onAnnotationClicked(annotation: Annotation) 11 | 12 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/PolyFeature.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Defines characteristics for poly features such as [Polyline] or [Polygon]. 5 | */ 6 | internal interface PolyFeature { 7 | 8 | fun getProperties(idForMap: String): Array 9 | 10 | fun getLayerName(): String 11 | 12 | fun getStringMapAsArray(properties: Map): Array { 13 | val out = arrayOfNulls(properties.size * 2) 14 | var i = 0 15 | for ((key, value) in properties) { 16 | out[i++] = key 17 | out[i++] = value 18 | } 19 | return out 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/PolyPointAnnotationOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | /** 4 | * Base abstract class for composing styling of poly point shapes e.g. [Polyline], [Polygon]. 5 | */ 6 | @Suppress("UNCHECKED_CAST") 7 | abstract class PolyPointAnnotationOptions { 8 | 9 | internal var strokeWidth: Int = Integer.MIN_VALUE 10 | internal var strokeColor: String = "" 11 | internal var strokeOutlineColor: String = "" 12 | internal var strokeOutlineWidth: Int = Integer.MIN_VALUE 13 | internal var lineJoinType: JoinType = JoinType.MITER 14 | internal var drawOrder: Int = Integer.MIN_VALUE 15 | internal var data: Any? = null 16 | var layerName: String = "" 17 | 18 | /** 19 | * Sets stroke width of the line. 20 | * 21 | * @param width 22 | */ 23 | fun strokeWidth(width: Int): T { 24 | this.strokeWidth = width 25 | return this as T 26 | } 27 | 28 | /** 29 | * Sets stroke color of the line. 30 | * 31 | * @param color 32 | */ 33 | fun strokeColor(color: String): T { 34 | this.strokeColor = color 35 | return this as T 36 | } 37 | 38 | /** 39 | * Sets stroke outline color of the line. 40 | * 41 | * @param color 42 | */ 43 | fun strokeOutlineColor(color: String): T { 44 | this.strokeOutlineColor = color 45 | return this as T 46 | } 47 | 48 | /** 49 | * Sets stroke outline width of the line. 50 | * 51 | * @param 52 | */ 53 | fun strokeOutlineWidth(width: Int): T { 54 | this.strokeOutlineWidth = width 55 | return this as T 56 | } 57 | 58 | /** 59 | * Sets the shape type of the joints in multi-segment lines. 60 | * 61 | * @param joinType 62 | */ 63 | fun lineJoinType(joinType: JoinType): T { 64 | this.lineJoinType = joinType 65 | return this as T 66 | } 67 | 68 | /** 69 | * Sets the poly shape's drawing order. The poly shape with higher draw order will be drawn above 70 | * the ones have lesser draw order. 71 | * 72 | * @param drawOrder of the poly shape 73 | */ 74 | fun drawOrder(drawOrder: Int): T { 75 | this.drawOrder = drawOrder 76 | return this as T 77 | } 78 | 79 | /** 80 | * Sets the given object related with the poly shapes. Setting related object of poly shape as a tag makes it 81 | * easier to reach the object rather than storing a Map data structure. 82 | * 83 | * @param tag any object related to the poly shape 84 | */ 85 | fun data(data: Any): T { 86 | this.data = data 87 | return this as T 88 | } 89 | 90 | /** 91 | * Sets the poly shape style with the style name that should existing in the YAML file. 92 | * 93 | * @param layerName 94 | */ 95 | fun layerName(layerName: String): T { 96 | this.layerName = layerName 97 | return this as T 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/PolygonOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | 5 | class PolygonOptions : PolyPointAnnotationOptions() { 6 | 7 | internal var points = emptyList>() 8 | internal var fillColor: String = "" 9 | 10 | init { 11 | drawOrder = 502 12 | } 13 | 14 | /** 15 | * Sets the points of the polygon. 16 | * 17 | * @param points list of polygon rings 18 | */ 19 | fun points(points: List>): PolygonOptions { 20 | this.points = points 21 | return this 22 | } 23 | 24 | /** 25 | * Sets the fill color of the polygon. 26 | * 27 | * @param color as hex like "#ff00ff" 28 | */ 29 | fun fillColor(color: String): PolygonOptions { 30 | this.fillColor = color 31 | return this 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/PolylineOptions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations 2 | 3 | import com.mapfit.android.anim.polyline.PolylineAnimation 4 | import com.mapfit.android.geometry.LatLng 5 | 6 | class PolylineOptions : PolyPointAnnotationOptions() { 7 | 8 | internal var points = emptyList() 9 | internal var lineCapType: CapType = CapType.BOUND 10 | internal var animation: PolylineAnimation? = null 11 | 12 | init { 13 | drawOrder = 503 14 | } 15 | 16 | /** 17 | * Sets the points for the polyline. 18 | * 19 | * @param points 20 | */ 21 | fun points(points: List): PolylineOptions { 22 | this.points = points 23 | return this 24 | } 25 | 26 | /** 27 | * Sets the shape type for the end of the lines. 28 | * 29 | * @param capType 30 | */ 31 | fun lineCapType(capType: CapType): PolylineOptions { 32 | this.lineCapType = capType 33 | return this 34 | } 35 | 36 | /** 37 | * Sets the animation for the polyline. 38 | */ 39 | fun animation(animation: T): PolylineOptions { 40 | this.animation = animation 41 | return this 42 | } 43 | 44 | 45 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/callback/OnMarkerAddedCallback.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations.callback 2 | 3 | import com.mapfit.android.annotations.Marker 4 | 5 | /** 6 | * Callback for listening marker addition to the map with [Geocoder]. 7 | * 8 | * Created by dogangulcan on 1/19/18. 9 | */ 10 | interface OnMarkerAddedCallback { 11 | 12 | fun onMarkerAdded(marker: Marker) 13 | 14 | fun onError(exception: Exception) 15 | 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/callback/OnMarkerClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations.callback 2 | 3 | import com.mapfit.android.annotations.Marker 4 | 5 | /** 6 | * Interface for listening [Marker] click events. 7 | * 8 | * Created by dogangulcan on 12/28/17. 9 | */ 10 | interface OnMarkerClickListener { 11 | 12 | fun onMarkerClicked(marker: Marker) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/callback/OnPolygonClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations.callback 2 | 3 | import com.mapfit.android.annotations.Polygon 4 | 5 | /** 6 | * Interface for listening [Polygon] click events. 7 | * 8 | * Created by dogangulcan on 3/9/18. 9 | */ 10 | interface OnPolygonClickListener { 11 | 12 | fun onPolygonClicked(polygon: Polygon) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/annotations/callback/OnPolylineClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.annotations.callback 2 | 3 | import com.mapfit.android.annotations.Polyline 4 | 5 | /** 6 | * Interface for listening [Polyline] click events. 7 | * 8 | * Created by dogangulcan on 3/9/18. 9 | */ 10 | interface OnPolylineClickListener { 11 | 12 | fun onPolylineClicked(polyline: Polyline) 13 | 14 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/camera/CameraAnimation.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.camera 2 | 3 | import android.graphics.drawable.Animatable 4 | 5 | interface CameraAnimation : Animatable -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/camera/CameraOptions.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.mapfit.android.camera 4 | 5 | import com.mapfit.android.MapController 6 | 7 | /** 8 | * Defines options for a [CameraAnimation]. 9 | */ 10 | open class CameraOptions { 11 | 12 | internal var duration = 0L 13 | internal var tiltAngle: Float = Float.NaN 14 | internal var tiltDuration = 0L 15 | internal var tiltEaseType = MapController.EaseType.QUART_IN_OUT 16 | internal var rotationAngle: Float = Float.NaN 17 | internal var rotationDuration = 0L 18 | internal var rotationEaseType = MapController.EaseType.QUART_IN_OUT 19 | internal var zoomLevel: Float = Float.NaN 20 | internal var zoomDuration = 0L 21 | internal var zoomEaseType = MapController.EaseType.QUART_IN_OUT 22 | 23 | /** 24 | * Sets duration for the animation. 25 | * 26 | * @param duration 27 | */ 28 | fun duration(duration: Long): T { 29 | this.duration = duration 30 | return this as T 31 | } 32 | 33 | /** 34 | * Sets the tilting animation options for the camera. 35 | * 36 | * @param angle angle in radians, 0 is to straight down 37 | * @param duration of the animation 38 | * @param easeType for the animation 39 | */ 40 | @JvmOverloads 41 | fun tiltTo( 42 | angle: Float, 43 | duration: Long = 0, 44 | easeType: MapController.EaseType = MapController.EaseType.QUART_IN_OUT 45 | ): T { 46 | this.tiltAngle = angle 47 | this.tiltDuration = duration 48 | this.tiltEaseType = easeType 49 | return this as T 50 | } 51 | 52 | /** 53 | * Sets the rotation animation options for the camera. 54 | * 55 | * @param angle angle in radians, 0 is facing north 56 | * @param duration of the animation 57 | * @param easeType for the animation 58 | */ 59 | @JvmOverloads 60 | fun rotateTo( 61 | angle: Float, 62 | duration: Long = 0, 63 | easeType: MapController.EaseType = MapController.EaseType.QUART_IN_OUT 64 | ): T { 65 | this.rotationAngle = angle 66 | this.rotationDuration = duration 67 | this.rotationEaseType = easeType 68 | return this as T 69 | } 70 | 71 | /** 72 | * Sets the zoom animation options for the camera. 73 | * 74 | * @param zoomLevel 75 | * @param duration of the animation 76 | * @param easeType for the animation 77 | */ 78 | @JvmOverloads 79 | fun zoomTo( 80 | zoomLevel: Float, 81 | duration: Long = 0, 82 | easeType: MapController.EaseType = MapController.EaseType.QUART_IN_OUT 83 | ): T { 84 | this.zoomLevel = zoomLevel 85 | this.zoomDuration = duration 86 | this.zoomEaseType = easeType 87 | return this as T 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/camera/Cinematography.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.camera 2 | 3 | import com.mapfit.android.MapfitMap 4 | import com.mapfit.android.anim.AnimationListener 5 | 6 | /** 7 | * Cinematography class makes it easier to implement camera animations by providing pre-made 8 | * animations. 9 | */ 10 | class Cinematography(private val mapfitMap: MapfitMap) { 11 | 12 | /** 13 | * Creates an animation with the given [CameraOptions]. 14 | * 15 | * @param cameraOptions options for camera animation 16 | * @param cameraAnimationCallback callback to listen to animation events 17 | */ 18 | fun create( 19 | cameraOptions: CameraOptions, 20 | cameraAnimationCallback: AnimationListener? = null 21 | ): CameraAnimation { 22 | return when (cameraOptions) { 23 | is OrbitTrajectory -> OrbitAnimation(cameraOptions, mapfitMap, cameraAnimationCallback) 24 | else -> Any() as CameraAnimation 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/camera/OrbitTrajectory.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.camera 2 | 3 | import com.mapfit.android.MapController 4 | import com.mapfit.android.geometry.LatLng 5 | 6 | 7 | /** 8 | * Defines orbit animation options for [OrbitAnimation]. 9 | */ 10 | class OrbitTrajectory : CameraOptions() { 11 | 12 | internal lateinit var pivotPosition: LatLng 13 | internal var loop: Boolean = true 14 | internal var centerToPivot = false 15 | internal var centeringDuration = 0L 16 | internal var centeringEaseType = MapController.EaseType.QUART_IN_OUT 17 | internal var speedMultiplier = 1f 18 | 19 | /** 20 | * Sets the pivot position for the camera to pan around of. 21 | * 22 | * @param position 23 | * @param centerToPivot set true to center to pivot 24 | * @param duration animation duration in milliseconds 25 | * @param easeType easing type for the animation 26 | */ 27 | fun pivot( 28 | position: LatLng, 29 | centerToPivot: Boolean = true, 30 | duration: Long = 0, 31 | easeType: MapController.EaseType = MapController.EaseType.QUART_IN_OUT 32 | ): OrbitTrajectory { 33 | this.pivotPosition = position 34 | this.centerToPivot = centerToPivot 35 | this.centeringDuration = duration 36 | this.centeringEaseType = easeType 37 | return this 38 | } 39 | 40 | /** 41 | * Sets if the camera animation will run infinitely. 42 | * 43 | * @param loop 44 | */ 45 | fun loop(loop: Boolean): OrbitTrajectory { 46 | this.loop = loop 47 | return this 48 | } 49 | 50 | /** 51 | * Sets the multiplier for rotation speed. For half speed, you can set `0.5f` where `1` is default 52 | * speed. Positive values will rotate anti-clockwise whereas negative values will rotate 53 | * clockwise. 54 | * 55 | * @param multiplier 56 | */ 57 | fun speedMultiplier(multiplier: Float): OrbitTrajectory { 58 | this.speedMultiplier = multiplier 59 | return this 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/compass/CompassListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.compass 2 | 3 | /** 4 | * Interface to listen orientation change events. @see [CompassProvider] 5 | * 6 | * Created by dogangulcan on 3/5/21. 7 | */ 8 | internal interface CompassListener { 9 | 10 | fun onOrientationChanged(angle: Float) 11 | 12 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/DirectionsCallback.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions 2 | 3 | import com.mapfit.android.directions.model.Route 4 | 5 | /** 6 | * Callback to listen [Directions] result. 7 | * 8 | * Created by dogangulcan on 2/4/18. 9 | */ 10 | interface DirectionsCallback { 11 | 12 | fun onSuccess(route: Route) 13 | 14 | fun onError(message: String, e: Exception) 15 | 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/DirectionsParser.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions 2 | 3 | import com.mapfit.android.exceptions.MapfitAuthorizationException 4 | import okhttp3.Response 5 | import org.json.JSONObject 6 | import java.security.InvalidParameterException 7 | 8 | /** 9 | * Internally used. 10 | * 11 | * Created by dogangulcan on 2/4/18. 12 | */ 13 | internal class DirectionsParser { 14 | 15 | fun parseError(response: Response?, rawResponseJson: JSONObject): Pair { 16 | 17 | return when (response?.code()) { 18 | 403 -> Pair("Mapfit Authorization Exception", MapfitAuthorizationException()) 19 | 400 -> parseResponseForError(rawResponseJson) 20 | else -> getDefaultException() 21 | } 22 | } 23 | 24 | private fun parseResponseForError(errorJson: JSONObject): Pair { 25 | 26 | return if (errorJson.has("response_type")) { 27 | when (errorJson.getInt("response_type")) { 28 | 0 -> Pair( 29 | "Unable to retrieve directions. Check if you have set an origin and destination address or location properly.", 30 | InvalidParameterException() 31 | ) 32 | else -> { 33 | getDefaultException() 34 | } 35 | } 36 | } else { 37 | getDefaultException() 38 | } 39 | } 40 | 41 | private fun getDefaultException() = 42 | Pair( 43 | "Unable to retrieve directions due to an unexpected error.", 44 | Exception("Unable to retrieve directions due to an unexpected error") 45 | ) 46 | 47 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/DirectionsType.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions 2 | 3 | /** 4 | * Directions types available for Mapfit Directions API. 5 | * 6 | * Created by dogangulcan on 2/5/18. 7 | */ 8 | enum class DirectionsType(private val type: String) { 9 | DRIVING("driving"), 10 | WALKING("walking"), 11 | CYCLING("cycling"); 12 | 13 | internal fun getName(): String { 14 | return type 15 | } 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Leg.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | /** 4 | * An individual step within the set of directions returned by the Directions API. 5 | * 6 | * Created by dogangulcan on 2/4/18. 7 | */ 8 | data class Leg( 9 | val summary: Summary, 10 | val shape: String, 11 | val maneuvers: List 12 | ) 13 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Location.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | import com.squareup.moshi.Json 4 | 5 | /** 6 | * Created by dogangulcan on 2/4/18. 7 | */ 8 | data class Location( 9 | val lon: Double, 10 | @field:Json(name = "side_of_street") val sideOfStreet: String, 11 | val type: String, 12 | val lat: Double 13 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Maneuver.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | import com.squareup.moshi.Json 4 | 5 | /** 6 | * Created by dogangulcan on 2/4/18. 7 | */ 8 | data class Maneuver( 9 | @field:Json(name = "begin_shape_index") val beginShapeIndex: Int, 10 | @field:Json(name = "travel_mode") val travelMode: String, 11 | val instruction: String, 12 | val length: Double, 13 | @field:Json(name = "street_names") val streetNames: List, 14 | @field:Json(name = "end_shape_index") val endShapeIndex: Int, 15 | val time: Int, 16 | val type: Int, 17 | @field:Json(name = "verbal_pre_transition_instruction") val verbalPreTransitionInstruction: String, 18 | @field:Json(name = "travel_type") val travelType: String 19 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Route.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | import com.mapfit.android.geometry.LatLngBounds 4 | import com.squareup.moshi.Json 5 | 6 | /** 7 | * Route of a trip from the origin to the destination. 8 | * 9 | * Created by dogangulcan on 2/4/18. 10 | */ 11 | data class Route( 12 | val trip: Trip = Trip(), 13 | var destinationLocation: List = listOf(), 14 | @field:Json(name = "sourceLocation") var originLocation: List = listOf(), 15 | @field:Transient var viewport: LatLngBounds = LatLngBounds() 16 | ) 17 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Summary.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | import com.squareup.moshi.Json 4 | 5 | /** 6 | * Created by dogangulcan on 2/4/18. 7 | */ 8 | data class Summary( 9 | @field:Json(name = "min_lon") val minLon: Double = 0.0, 10 | @field:Json(name = "max_lat") val maxLat: Double = 0.0, 11 | @field:Json(name = "max_lon") val maxLon: Double = 0.0, 12 | val length: Double = 0.0, 13 | val time: Int = 0, 14 | @field:Json(name = "min_lat") val minLat: Double = 0.0 15 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/directions/model/Trip.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.directions.model 2 | 3 | import com.squareup.moshi.Json 4 | 5 | /** 6 | * Created by dogangulcan on 2/4/18. 7 | */ 8 | data class Trip( 9 | val summary: Summary = Summary(), 10 | @field:Json(name = "status_message") val statusMessage: String = "", 11 | val legs: List = listOf(), 12 | val language: String = "", 13 | val locations: List = listOf(), 14 | val units: String = "", 15 | val status: Int = 0 16 | ) 17 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/exceptions/MapfitAuthorizationException.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.exceptions 2 | 3 | /** 4 | * Exception thrown when authorization is not valid. 5 | * 6 | * Created by dogangulcan on 1/18/18. 7 | */ 8 | class MapfitAuthorizationException : RuntimeException( 9 | "\nMapfit API key is not authorized." + 10 | "\nPlease visit https://mapfit.com/getstarted to get a new API key.\n" 11 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/exceptions/MapfitConfigurationException.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.exceptions 2 | 3 | /** 4 | * Created by dogangulcan on 1/18/18. 5 | */ 6 | class MapfitConfigurationException : RuntimeException( 7 | "\nUsing MapView requires setting a valid access token. Use Mapfit.getInstance(context, apiKey)" + 8 | " to setup Mapfit." + 9 | "\nIf you don't have an api key, you can get from https://mapfit.com/getstarted.\n" 10 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/GeocoderCallback.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder 2 | 3 | import com.mapfit.android.geocoder.model.Address 4 | 5 | /** 6 | * Callback used to get responses and errors from [Geocoder]. 7 | * 8 | * Created by dogangulcan on 1/18/18. 9 | */ 10 | interface GeocoderCallback { 11 | 12 | fun onSuccess(addressList: List
) 13 | 14 | fun onError(message: String, e: Exception) 15 | 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/model/Address.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder.model 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | import com.mapfit.android.geometry.LatLngBounds 5 | 6 | /** 7 | * Class representing the result from the Mapfit Geocoding API, including the normalized address 8 | * components, geographical coordinate position and the (optional) building polygon. 9 | * 10 | * Created by dogangulcan on 1/18/18. 11 | */ 12 | data class Address internal constructor( 13 | val streetAddress: String = "", 14 | val country: String = "", 15 | val adminArea: String = "", 16 | val locality: String = "", 17 | val postalCode: String = "", 18 | val neighborhood: String = "", 19 | val building: Building, 20 | val viewport: LatLngBounds?, 21 | val lat: Double = 0.0, 22 | val lng: Double = 0.0, 23 | val responseType: ResponseType?, 24 | val entrances: List = mutableListOf() 25 | ) { 26 | 27 | internal fun getPrimaryEntrance(): LatLng = 28 | if (entrances.isNotEmpty()) { 29 | LatLng(entrances.first().lat, entrances.first().lng) 30 | } else { 31 | LatLng(lat, lng) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/model/Building.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder.model 2 | 3 | import com.mapfit.android.geometry.LatLng 4 | 5 | /** 6 | * Class representing the Building polygon and the polygon type. 7 | * 8 | * Created by dogangulcan on 2/22/18. 9 | */ 10 | data class Building( 11 | val polygon: List> = emptyList(), 12 | val type: String = "" 13 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/model/Entrance.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder.model 2 | 3 | /** 4 | * Data class for defining an entrance point of a place. 5 | * 6 | * Created by dogangulcan on 1/18/18. 7 | */ 8 | data class Entrance( 9 | val lat: Double, 10 | val lng: Double, 11 | val entranceType: EntranceType? 12 | ) -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/model/EntranceType.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder.model 2 | 3 | /** 4 | * Entrance types of a place. 5 | * 6 | * Created by dogangulcan on 1/18/18. 7 | */ 8 | enum class EntranceType(val entranceType: String) { 9 | PEDESTRIAN_PRIMARY("pedestrian-primary"), 10 | PEDESTRIAN_SECONDARY("pedestrian-secondary"), 11 | ALL_PEDESTRIAN("all-pedestrian"), 12 | LOADING("loading"), 13 | SERVICE("service"), 14 | PARKING("parking"), 15 | ALL("all"), 16 | INTERPOLATED("interpolated") 17 | } 18 | 19 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geocoder/model/ResponseType.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geocoder.model 2 | 3 | /** 4 | * Status code for API result. 5 | * 6 | * Created by dogangulcan on 1/18/18. 7 | */ 8 | enum class ResponseType(var code: Int) { 9 | ERROR(0), 10 | SUCCESS(1), 11 | INTERPOLATED(2), 12 | ZERO_RESULTS(3), 13 | ENTRANCE(4), 14 | FALLBACK(13) 15 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geometry/GeoExtentions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geometry 2 | 3 | import android.util.Log 4 | 5 | /** 6 | * Extension functions for geo related classes. 7 | * 8 | * Created by dogangulcan on 2/20/18. 9 | */ 10 | 11 | internal fun LatLng.isValid(): Boolean { 12 | 13 | val latRegex = """^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)$""".toRegex() 14 | val lonRegex = """^\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)${'$'}""".toRegex() 15 | 16 | val isLatValid = latRegex.containsMatchIn(lat.toString()) 17 | val isLonValid = lonRegex.containsMatchIn(lng.toString()) 18 | 19 | if (!isLatValid) { 20 | Log.e("Mapfit", "Invalid latitude: $lat. Should be in the range [-90, 90].") 21 | } 22 | 23 | if (!isLatValid) { 24 | Log.e("Mapfit", "Invalid longitude: $lng. Should be in the range [-180, 180).") 25 | } 26 | 27 | return isLatValid && isLonValid 28 | } 29 | 30 | internal fun LatLng.isEmpty() = lat == 0.0 && lng == 0.0 31 | 32 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geometry/GeoUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("GeoUtils") 2 | 3 | package com.mapfit.android.geometry 4 | 5 | import android.graphics.PointF 6 | 7 | 8 | /** 9 | * Returns the unweighted center for a list of [LatLng]. 10 | * 11 | * @param coordinates 12 | * @return [LatLng] center of the given coordinates 13 | */ 14 | fun getCenterLatLng(coordinates: List): LatLng { 15 | if (coordinates.size == 1) { 16 | return coordinates.first() 17 | } 18 | 19 | var x = 0.0 20 | var y = 0.0 21 | var z = 0.0 22 | 23 | coordinates.forEach { latLng -> 24 | val latitude = Math.toRadians(latLng.lat) 25 | val longitude = Math.toRadians(latLng.lng) 26 | 27 | x += Math.cos(latitude) * Math.cos(longitude) 28 | y += Math.cos(latitude) * Math.sin(longitude) 29 | z += Math.sin(latitude) 30 | } 31 | 32 | val total = coordinates.size 33 | 34 | x /= total 35 | y /= total 36 | z /= total 37 | 38 | val centralLongitude = Math.atan2(y, x) 39 | val centralSquareRoot = Math.sqrt(x * x + y * y) 40 | val centralLatitude = Math.atan2(z, centralSquareRoot) 41 | 42 | return LatLng(Math.toDegrees(centralLatitude), Math.toDegrees(centralLongitude)) 43 | 44 | } 45 | 46 | /** 47 | * Returns the middle point of two coordinates. 48 | * 49 | * @param first 50 | * @param second 51 | * @return [LatLng] mid point of first and second 52 | */ 53 | fun midPoint(first: LatLng, second: LatLng): LatLng { 54 | val dLon = Math.toRadians(second.lng - first.lng) 55 | 56 | val radLat1 = Math.toRadians(first.lat) 57 | val radLat2 = Math.toRadians(second.lat) 58 | val radLon1 = Math.toRadians(first.lng) 59 | 60 | val bX = Math.cos(radLat2) * Math.cos(dLon) 61 | val bY = Math.cos(radLat2) * Math.sin(dLon) 62 | val lat3 = Math.atan2( 63 | Math.sin(radLat1) + Math.sin(radLat2), 64 | Math.sqrt((Math.cos(radLat1) + bX) * (Math.cos(radLat1) + bX) + bY * bY) 65 | ) 66 | val lon3 = radLon1 + Math.atan2(bY, Math.cos(radLat1) + bX) 67 | 68 | return LatLng(Math.toDegrees(lat3), Math.toDegrees(lon3)) 69 | } 70 | 71 | /** 72 | * Calculates and returns the screen position for the LatLng value. 73 | * 74 | * @param zoomLevel 75 | */ 76 | fun LatLng.toPointF(zoomLevel: Float): PointF { 77 | val worldWidth = toWorldWidthPixels(zoomLevel) 78 | 79 | val x = lng / 360 + .5 80 | val sinY = Math.sin(Math.toRadians(lat)) 81 | val y = 0.5 * Math.log((1 + sinY) / (1 - sinY)) / -(2 * Math.PI) + .5 82 | 83 | return PointF((x * worldWidth).toFloat(), (y * worldWidth).toFloat()) 84 | } 85 | 86 | /** 87 | * Calculates and returns the LatLng value for the screen position. 88 | * 89 | * @param zoomLevel 90 | */ 91 | fun PointF.toLatLng(zoomLevel: Float): LatLng { 92 | val worldWidth = toWorldWidthPixels(zoomLevel) 93 | 94 | val x = x / worldWidth - 0.5 95 | val lng = x * 360 96 | 97 | val y = .5 - y / worldWidth 98 | val lat = 90 - Math.toDegrees(Math.atan(Math.exp(-y * 2.0 * Math.PI)) * 2) 99 | 100 | return LatLng(lat, lng) 101 | } 102 | 103 | /** 104 | * Calculates world width for the given zoom level. 105 | * 106 | * @param zoomLevel 107 | */ 108 | fun toWorldWidthPixels(zoomLevel: Float) = (256 * Math.pow(2.0, zoomLevel.toDouble())).toFloat() 109 | 110 | /** 111 | * Calculates the middle angle between 3 coordinates. 112 | * 113 | * @param p1 first point 114 | * @param p2 middle point 115 | * @param p3 last point 116 | */ 117 | fun calculateMidAngle( 118 | p1: LatLng, 119 | p2: LatLng, 120 | p3: LatLng 121 | ): Double { 122 | val numerator = 123 | p2.lng * (p1.lat - p3.lat) + p1.lng * (p3.lat - p2.lat) + p3.lng * (p2.lat - p1.lat) 124 | val denominator = (p2.lat - p1.lat) * (p1.lat - p3.lat) + (p2.lng - p1.lng) * (p1.lng - p3.lng) 125 | val ratio = numerator / denominator 126 | 127 | val angleRad = Math.atan(ratio) 128 | var angleDeg = angleRad * 180 / Math.PI 129 | 130 | if (angleDeg < 0) { 131 | angleDeg += 180 132 | } 133 | 134 | return angleDeg 135 | } 136 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geometry/LatLng.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geometry 2 | 3 | import android.os.Parcelable 4 | import android.support.annotation.FloatRange 5 | import kotlinx.android.parcel.Parcelize 6 | 7 | /** 8 | * Immutable class holding a pair of latitude and longitude coordinates in degrees. 9 | * 10 | * @param lat Latitude, in degrees. 11 | * @param lng Longitude, in degrees. 12 | */ 13 | @Parcelize 14 | data class LatLng( 15 | @FloatRange(from = -90.0, to = 90.0) val lat: Double = 0.0, 16 | @FloatRange(from = -180.0, to = 180.0) val lng: Double = 0.0 17 | ) : Parcelable { 18 | init { 19 | isValid() 20 | } 21 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/geometry/LatLngBounds.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geometry 2 | 3 | import android.content.res.Resources 4 | import com.mapfit.android.MapOptions 5 | 6 | 7 | /** 8 | * Defines a rectangle with north east and south west coordinates. 9 | * 10 | * Created by dogangulcan on 1/4/18. 11 | */ 12 | class LatLngBounds( 13 | val northEast: LatLng = LatLng(), 14 | val southWest: LatLng = LatLng() 15 | ) { 16 | 17 | val center: LatLng by lazy { 18 | midPoint(northEast, southWest) 19 | } 20 | 21 | private val mapSideLength by lazy { 22 | 256 * (Resources.getSystem()?.displayMetrics?.density ?: 1f) 23 | } 24 | 25 | class Builder { 26 | 27 | private val latLngList = mutableListOf() 28 | 29 | /** 30 | * @param [LatLng] point to be included in the bounds 31 | */ 32 | fun include(latLng: LatLng) { 33 | latLngList.add(latLng) 34 | } 35 | 36 | /** 37 | * Builds [LatLngBounds] with the current list of [LatLng] points. 38 | */ 39 | fun build(): LatLngBounds { 40 | var south: Double? = null 41 | var west: Double? = null 42 | var north: Double? = null 43 | var east: Double? = null 44 | 45 | latLngList.forEach { 46 | if (south == null || south!! > it.lat) south = it.lat 47 | if (west == null || west!! > it.lng) west = it.lng 48 | if (north == null || north!! < it.lat) north = it.lat 49 | if (east == null || east!! < it.lng) east = it.lng 50 | } 51 | 52 | val northEast = LatLng(north ?: 0.0, east ?: 0.0) 53 | val southWest = LatLng(south ?: 0.0, west ?: 0.0) 54 | 55 | return LatLngBounds(northEast, southWest) 56 | } 57 | } 58 | 59 | /** 60 | * Calculates visible bounds of the map. 61 | * 62 | * @param viewWidth of the MapView 63 | * @param viewHeight of the MapView 64 | * @param padding padding for the bounds 65 | * @param vanishingPointOffset if scene camera is having vanishing point 66 | * @return center point and zoom level 67 | */ 68 | fun getVisibleBounds( 69 | viewWidth: Int, 70 | viewHeight: Int, 71 | padding: Float, 72 | vanishingPointOffset: Pair = Pair(0f, 0f) 73 | ): Pair { 74 | val reversePadding = if ((1 - padding) == 0f) 1f else (1 - padding) 75 | 76 | val latFraction = (latRad(northEast.lat) - latRad(southWest.lat)) / Math.PI 77 | val lngDiff = northEast.lng - southWest.lng 78 | val lngFraction = (if (lngDiff < 0) lngDiff + 360 else lngDiff) / 360 79 | val latZoom = zoom(viewHeight.toDouble(), reversePadding, latFraction) 80 | val lngZoom = zoom(viewWidth.toDouble(), reversePadding, lngFraction) 81 | val zoom = Math.min(Math.min(latZoom, lngZoom), MapOptions.MAP_MAX_ZOOM).toFloat() 82 | 83 | val normalizedCenter = 84 | if (vanishingPointOffset.first > 0 || vanishingPointOffset.second > 0) { 85 | val correctedCenter = center.toPointF(zoom) 86 | correctedCenter.offset(vanishingPointOffset.first, vanishingPointOffset.second) 87 | correctedCenter.toLatLng(zoom) 88 | } else { 89 | center 90 | } 91 | 92 | return Pair(normalizedCenter, zoom) 93 | } 94 | 95 | private fun latRad(lat: Double): Double { 96 | val sin = Math.sin(lat * Math.PI / 180) 97 | val radX2 = Math.log((1 + sin) / (1 - sin)) / 2 98 | return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2 99 | } 100 | 101 | private fun zoom(mapPx: Double, padding: Float, fraction: Double): Double { 102 | return Math.log((mapPx / mapSideLength.toDouble() / fraction) * padding) / .693147180559945309417 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/location/LocationListener.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.location 2 | 3 | import android.location.Location 4 | 5 | /** 6 | * Interface for listening device location changes. 7 | * 8 | * Created by dogangulcan on 3/2/18. 9 | */ 10 | interface LocationListener { 11 | 12 | fun onLocation(location: Location) 13 | 14 | fun onProviderStatus(status: ProviderStatus) 15 | 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/location/LocationPriority.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.location 2 | 3 | /** 4 | * Location request priorities. 5 | */ 6 | enum class LocationPriority(private val priority: Int) { 7 | /** 8 | * Most accurate location will be obtained. It will consume more power. Expect an accuracy of 9 | * less than 100 meters. 10 | */ 11 | HIGH_ACCURACY(3), 12 | 13 | /** 14 | * Focuses on low power consumption. Expect an accuracy greater than 500 meters. 15 | */ 16 | LOW_ACCURACY(1); 17 | 18 | internal fun getPriority(): Int { 19 | return priority 20 | } 21 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/location/LocationRequest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.location 2 | 3 | /** 4 | * Bundle for location request preferences. 5 | * 6 | * Created by dogangulcan on 3/2/18. 7 | * 8 | * @param locationPriority 9 | * @param interval location will be obtained 10 | * @param minimumDisplacement in meters to obtain new location 11 | * @param updateCount number of location updates to be obtained 12 | */ 13 | data class LocationRequest( 14 | var locationPriority: LocationPriority = LocationPriority.HIGH_ACCURACY, 15 | var interval: Long = DEFAULT_LOCATION_UPDATE_INTERVAL, 16 | var minimumDisplacement: Float = DEFAULT_LOCATION_UPDATE_DISTANCE, 17 | var updateCount: Int = -1 18 | ) 19 | 20 | private const val DEFAULT_LOCATION_UPDATE_INTERVAL = 1000L 21 | private const val DEFAULT_LOCATION_UPDATE_DISTANCE = 1f -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/location/LocationUtils.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.location 2 | 3 | import android.content.Context 4 | import android.location.Location 5 | 6 | /** 7 | * Utils for locations. 8 | * 9 | * Created by dogangulcan on 3/1/18. 10 | */ 11 | 12 | private const val TIME_CONSTANT_MILLIS = 3000 13 | private const val EARTH_RADIUS = 6371009 14 | private const val TILE_SIZE = 256 15 | 16 | 17 | /** 18 | * Determines whether one Location reading is better than the current Location fix. 19 | * 20 | * @param location The new Location that you want to evaluate 21 | * @param currentBestLocation The current Location fix, to which you want to compare the new one 22 | */ 23 | internal fun isBetterLocation(location: Location, currentBestLocation: Location?): Boolean { 24 | if (currentBestLocation == null) { 25 | // A new location is always better than no location 26 | return true 27 | } 28 | 29 | // Check whether the new location fix is newer or older 30 | val timeDelta = location.time - currentBestLocation.time 31 | val isSignificantlyNewer = timeDelta > TIME_CONSTANT_MILLIS 32 | val isSignificantlyOlder = timeDelta < -TIME_CONSTANT_MILLIS 33 | val isNewer = timeDelta > 0 34 | 35 | // If it's been more than two minutes since the current location, use the new location 36 | // because the user has likely moved 37 | if (isSignificantlyNewer) { 38 | return true 39 | // If the new location is more than two minutes older, it must be worse 40 | } else if (isSignificantlyOlder) { 41 | return false 42 | } 43 | 44 | // Check whether the new location fix is more or less accurate 45 | val accuracyDelta = (location.accuracy - currentBestLocation.accuracy).toInt() 46 | val isLessAccurate = accuracyDelta > 0 47 | val isMoreAccurate = accuracyDelta < 0 48 | val isSignificantlyLessAccurate = accuracyDelta > 200 49 | 50 | // Check if the old and new location are from the same provider 51 | val isFromSameProvider = isSameProvider( 52 | location.provider, 53 | currentBestLocation.provider 54 | ) 55 | 56 | // Determine location quality using a combination of timeliness and accuracy 57 | if (isMoreAccurate) { 58 | return true 59 | } else if (isNewer && !isLessAccurate) { 60 | return true 61 | } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 62 | return true 63 | } 64 | return false 65 | } 66 | 67 | /** 68 | * Checks whether two providers are the same 69 | */ 70 | private fun isSameProvider(provider1: String?, provider2: String?): Boolean { 71 | return if (provider1 == null) { 72 | provider2 == null 73 | } else provider1 == provider2 74 | } 75 | 76 | /** 77 | * Calculates and returns pixels per meter according to given latitude and zoom level. 78 | * 79 | * @return pixels per meter 80 | */ 81 | internal fun getPixelsPerMeter(context: Context, lat: Double, zoom: Float): Double { 82 | val pixelsPerTile = (TILE_SIZE * context.resources.displayMetrics.densityDpi) / 160 83 | val numTiles = Math.pow(2.0, zoom.toDouble() - 3) 84 | val metersPerTile = Math.cos(Math.toRadians(lat)) * EARTH_RADIUS / numTiles 85 | return pixelsPerTile / metersPerTile 86 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/location/ProviderStatus.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.location 2 | 3 | /** 4 | * Represents location provider status. 5 | * 6 | * Created by dogangulcan on 3/2/18. 7 | */ 8 | enum class ProviderStatus { 9 | 10 | /** 11 | * States that the location provider is enabled and there will be location updates. 12 | */ 13 | ENABLED, 14 | 15 | /** 16 | * States that the location provider is disabled and there won't be location updates. 17 | */ 18 | DISABLED, 19 | 20 | /** 21 | * The provider is out of service. 22 | */ 23 | OUT_OF_SERVICE, 24 | 25 | /** 26 | * The provider is expected to be available in near future. 27 | */ 28 | TEMPORARILY_UNAVAILABLE, 29 | 30 | } 31 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/utils/CommonExtentions.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.utils 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.graphics.* 6 | import android.graphics.Paint.* 7 | import android.graphics.drawable.BitmapDrawable 8 | import android.graphics.drawable.Drawable 9 | 10 | 11 | /** 12 | * Created by dogangulcan on 1/23/18. 13 | */ 14 | 15 | internal fun Context.startActivitySafe(intent: Intent) { 16 | if (intent.resolveActivity(packageManager) != null) { 17 | startActivity(intent) 18 | } 19 | } 20 | 21 | /** 22 | * Returns rotated 23 | */ 24 | internal fun Bitmap.rotate(angle: Float): Bitmap { 25 | val w = width 26 | val h = height 27 | 28 | var newW = w 29 | var newH = h 30 | if (angle == 90f || angle == 270f) { 31 | newW = h 32 | newH = w 33 | } 34 | val rotatedBitmap = Bitmap.createBitmap(newW, newH, config) 35 | val canvas = Canvas(rotatedBitmap) 36 | 37 | val rect = Rect(0, 0, newW, newH) 38 | val matrix = Matrix() 39 | val px = rect.exactCenterX() 40 | val py = rect.exactCenterY() 41 | matrix.postTranslate(-width / 2f, -height / 2f) 42 | matrix.postRotate(angle) 43 | matrix.postTranslate(px, py) 44 | canvas.drawBitmap( 45 | this, 46 | matrix, 47 | Paint(ANTI_ALIAS_FLAG or DITHER_FLAG or FILTER_BITMAP_FLAG) 48 | ) 49 | matrix.reset() 50 | 51 | return rotatedBitmap 52 | } 53 | 54 | /** 55 | * Converts drawable to bitmap. 56 | * 57 | * @return bitmap relative to screen density 58 | */ 59 | internal fun Drawable.toBitmap(context: Context): Bitmap { 60 | val density = context.resources.displayMetrics.densityDpi 61 | val bitmapDrawable = this as BitmapDrawable 62 | bitmapDrawable.setTargetDensity(density) 63 | val bitmap = bitmapDrawable.bitmap 64 | bitmap.density = density 65 | return bitmap 66 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/utils/CommonUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("CommonUtils") 2 | 3 | package com.mapfit.android.utils 4 | 5 | import android.content.Context 6 | import android.graphics.Bitmap 7 | import android.graphics.BitmapFactory 8 | import android.graphics.Canvas 9 | import android.graphics.drawable.Drawable 10 | import android.net.ConnectivityManager 11 | import android.os.Build 12 | import android.support.annotation.DrawableRes 13 | import android.support.v4.content.ContextCompat 14 | import android.support.v4.graphics.drawable.DrawableCompat 15 | import android.util.Log 16 | import com.mapfit.android.MapOptions.Companion.MAP_MAX_ZOOM 17 | import com.mapfit.android.MapOptions.Companion.MAP_MIN_ZOOM 18 | import com.mapfit.android.Mapfit 19 | import kotlinx.coroutines.experimental.Deferred 20 | import kotlinx.coroutines.experimental.async 21 | import java.math.BigInteger 22 | import java.net.URL 23 | import java.nio.ByteBuffer 24 | import java.util.* 25 | 26 | 27 | /** 28 | * Commonly used utility functions. 29 | * 30 | * Created by dogangulcan on 12/21/17. 31 | */ 32 | 33 | 34 | fun isValidZoomLevel(zoomLevel: Float): Boolean { 35 | return if (zoomLevel !in MAP_MIN_ZOOM..MAP_MAX_ZOOM) { 36 | Log.w("Mapfit", "Zoom level must be between $MAP_MIN_ZOOM and $MAP_MAX_ZOOM") 37 | false 38 | } else { 39 | true 40 | } 41 | } 42 | 43 | internal fun loadImageFromUrl(url: String): Deferred = async { 44 | if (isValidImageUrl(url) && isNetworkAvailable()) { 45 | try { 46 | val inputStream = URL(url).openStream() 47 | val drawable = Drawable.createFromStream(inputStream, "") 48 | 49 | drawable 50 | } catch (e: Exception) { 51 | logException(e) 52 | null 53 | } 54 | } else { 55 | Log.w("Mapfit", "Invalid image url $url") 56 | null 57 | } 58 | } 59 | 60 | internal fun isValidImageUrl(url: String): Boolean { 61 | val imgRg = """(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*\.(?:jpg|gif|png))""".toRegex() 62 | return imgRg.containsMatchIn(url) 63 | } 64 | 65 | internal fun isNetworkAvailable(): Boolean { 66 | val connectivityManager = 67 | Mapfit.getContext()?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 68 | val activeNetworkInfo = connectivityManager.activeNetworkInfo 69 | return activeNetworkInfo != null && activeNetworkInfo.isConnected 70 | } 71 | 72 | internal fun getBitmapFromVectorDrawable(context: Context, drawableId: Int): Bitmap { 73 | var drawable = ContextCompat.getDrawable(context, drawableId) 74 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 75 | drawable = DrawableCompat.wrap(drawable!!).mutate() 76 | } 77 | 78 | val bitmap = Bitmap.createBitmap( 79 | drawable!!.intrinsicWidth, 80 | drawable.intrinsicHeight, Bitmap.Config.ARGB_8888 81 | ) 82 | val canvas = Canvas(bitmap) 83 | drawable.setBounds(0, 0, canvas.width, canvas.height) 84 | drawable.draw(canvas) 85 | 86 | return bitmap 87 | } 88 | 89 | internal fun generateUniqueId(): Long { 90 | var id: Long 91 | do { 92 | val uid = UUID.randomUUID() 93 | val buffer = ByteBuffer.wrap(ByteArray(16)) 94 | buffer.putLong(uid.leastSignificantBits) 95 | buffer.putLong(uid.mostSignificantBits) 96 | id = BigInteger(buffer.array()).toLong() 97 | } while (id < 0) 98 | 99 | return id 100 | } 101 | 102 | internal fun getBitmapFromDrawableID(context: Context, @DrawableRes drawableId: Int): Bitmap? { 103 | val options = BitmapFactory.Options() 104 | options.inTargetDensity = context.resources.displayMetrics.densityDpi 105 | return BitmapFactory.decodeResource(context.resources, drawableId, options) 106 | } 107 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/utils/DebugUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("DebugUtils") 2 | 3 | package com.mapfit.android.utils 4 | 5 | import com.mapfit.android.BuildConfig 6 | 7 | /** 8 | * Created by dogangulcan on 1/23/18. 9 | */ 10 | 11 | 12 | internal fun logException(exception: Exception) { 13 | // if (BuildConfig.DEBUG) { 14 | // exception.printStackTrace() 15 | // } 16 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/utils/Loggers.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.utils 2 | 3 | import android.util.Log 4 | import com.mapfit.android.Mapfit 5 | 6 | /** 7 | * Logging functions. 8 | * 9 | * Created by dogangulcan on 3/15/18. 10 | */ 11 | 12 | 13 | internal fun logWarning(s: String) { 14 | Log.w(Mapfit.TAG, s) 15 | } 16 | 17 | internal fun logError(s: String) { 18 | Log.e(Mapfit.TAG, s) 19 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/android/utils/PolyUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("PolyUtils") 2 | 3 | package com.mapfit.android.utils 4 | 5 | import com.mapfit.android.geometry.LatLng 6 | 7 | /** 8 | * Decodes an encoded path string into a sequence of [LatLng]s. 9 | * 10 | * @param encodedPath 11 | */ 12 | fun decodePolyline(encodedPath: String): List { 13 | val len = encodedPath.length 14 | val decodedPath = ArrayList() 15 | var index = 0 16 | var lat = 0 17 | var lng = 0 18 | 19 | while (index < len) { 20 | var result = 1 21 | var shift = 0 22 | var b: Int 23 | do { 24 | b = encodedPath[index++].toInt() - 63 - 1 25 | result += b shl shift 26 | shift += 5 27 | } while (b >= 0x1f) 28 | lat += if (result and 1 != 0) (result shr 1).inv() else result shr 1 29 | 30 | result = 1 31 | shift = 0 32 | do { 33 | b = encodedPath[index++].toInt() - 63 - 1 34 | result += b shl shift 35 | shift += 5 36 | } while (b >= 0x1f) 37 | lng += if (result and 1 != 0) (result shr 1).inv() else result shr 1 38 | 39 | decodedPath.add(LatLng(lat * 1e-6, lng * 1e-6)) 40 | } 41 | 42 | return decodedPath 43 | } 44 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/tetragon/CachePolicy.java: -------------------------------------------------------------------------------- 1 | package com.mapfit.tetragon; 2 | 3 | import okhttp3.CacheControl; 4 | import okhttp3.HttpUrl; 5 | 6 | /** 7 | * A CachePolicy evaluates a {@link HttpUrl} and determines the {@link CacheControl} that should 8 | * apply to a request for that URL. 9 | */ 10 | public interface CachePolicy { 11 | /** 12 | * Apply a caching policy to a URL. 13 | * 14 | * @param url The URL being requested 15 | * @return The CacheControl to apply to the request, or {@code null} for the default behavior. 16 | */ 17 | CacheControl apply(HttpUrl url); 18 | } 19 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/tetragon/LabelPickResult.java: -------------------------------------------------------------------------------- 1 | package com.mapfit.tetragon; 2 | 3 | import android.support.annotation.Keep; 4 | 5 | import com.mapfit.android.geometry.LatLng; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * {@code LabelPickResult} represents labels that can be selected on the screen 11 | */ 12 | @Keep 13 | public class LabelPickResult { 14 | 15 | /** 16 | * Options for the type of LabelPickResult 17 | */ 18 | public enum LabelType { 19 | ICON, 20 | TEXT, 21 | } 22 | 23 | private LatLng coordinates; 24 | private LabelType type; 25 | private Map properties; 26 | 27 | private LabelPickResult(double longitude, double latitude, int type, Map properties) { 28 | this.properties = properties; 29 | this.coordinates = new LatLng(longitude, latitude); 30 | this.type = LabelType.values()[type]; 31 | } 32 | 33 | public LabelType getType() { 34 | return this.type; 35 | } 36 | 37 | /** 38 | * @return The coordinate of the feature for which this label has been created 39 | */ 40 | public LatLng getCoordinates() { 41 | return this.coordinates; 42 | } 43 | 44 | /** 45 | * @return A mapping of string keys to string or number values 46 | */ 47 | public Map getProperties() { 48 | return this.properties; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/tetragon/MarkerPickResult.java: -------------------------------------------------------------------------------- 1 | package com.mapfit.tetragon; 2 | 3 | import android.support.annotation.Keep; 4 | 5 | import com.mapfit.android.geometry.LatLng; 6 | 7 | /** 8 | * {@code MarkerPickResult} represents labels that can be selected on the screen 9 | */ 10 | @Keep 11 | public class MarkerPickResult { 12 | 13 | private com.mapfit.android.annotations.Marker marker; 14 | private LatLng coordinates; 15 | 16 | private MarkerPickResult(com.mapfit.android.annotations.Marker marker, double longitude, double latitude) { 17 | this.marker = marker; 18 | this.coordinates = new LatLng(longitude, latitude); 19 | } 20 | 21 | /** 22 | * @return The marker associated with the selection 23 | */ 24 | public com.mapfit.android.annotations.Marker getMarker() { 25 | return this.marker; 26 | } 27 | 28 | /** 29 | * @return The coordinate of the feature for which this label has been created 30 | */ 31 | public LatLng getCoordinates() { 32 | return coordinates; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/tetragon/SceneError.java: -------------------------------------------------------------------------------- 1 | package com.mapfit.tetragon; 2 | 3 | import android.support.annotation.Keep; 4 | 5 | import com.mapfit.android.MapController.Error; 6 | 7 | @Keep 8 | public class SceneError { 9 | 10 | private SceneUpdate sceneUpdate; 11 | private Error error; 12 | 13 | private SceneError(String sceneUpdatePath, String sceneUpdateValue, int error) { 14 | this.sceneUpdate = new SceneUpdate(sceneUpdatePath, sceneUpdateValue); 15 | this.error = Error.values()[error]; 16 | } 17 | 18 | public SceneUpdate getSceneUpdate() { 19 | return this.sceneUpdate; 20 | } 21 | 22 | public Error getError() { 23 | return this.error; 24 | } 25 | } -------------------------------------------------------------------------------- /android-sdk/src/main/java/com/mapfit/tetragon/SceneUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.tetragon 2 | 3 | /** 4 | * Represents a data structure to specify a yaml path and the corresponding value. 5 | * 6 | * @param path path of the property to be changed. use dot(".") to declare scopes. e.g. "global.show_transit" 7 | * @param value yaml string which will update the value at the specified path 8 | */ 9 | data class SceneUpdate(val path: String, val value: String) { 10 | 11 | override fun toString() = "$path $value" 12 | 13 | } 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_card_backing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_card_backing.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_compass.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_current_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_current_location.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_current_location_passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_current_location_passive.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_re_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_re_center.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_re_center_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_re_center_off.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-hdpi/mf_user_loc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-hdpi/mf_user_loc.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_compass.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_current_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_current_location.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_current_location_passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_current_location_passive.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_re_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_re_center.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_re_center_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_re_center_off.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-mdpi/mf_user_loc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-mdpi/mf_user_loc.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_card_backing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_card_backing.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_compass.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_current_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_current_location.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_current_location_passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_current_location_passive.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_re_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_re_center.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_re_center_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_re_center_off.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xhdpi/mf_user_loc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xhdpi/mf_user_loc.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_card_backing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_card_backing.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_compass.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_current_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_current_location.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_current_location_passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_current_location_passive.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_re_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_re_center.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_re_center_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_re_center_off.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxhdpi/mf_user_loc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxhdpi/mf_user_loc.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_compass.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_current_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_current_location.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_current_location_passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_current_location_passive.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_place_info_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_place_info_bg.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_re_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_re_center.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_re_center_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_re_center_off.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable-xxxhdpi/mf_user_loc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable-xxxhdpi/mf_user_loc.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_accuracy_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_marker_dot.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_transparent.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_user_direction.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_watermark_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 76 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_watermark_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 82 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_watermarklight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable/mf_watermarklight.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_zoom_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/android-sdk/src/main/res/drawable/mf_zoom_bg.png -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_zoom_break.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_zoom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/drawable/mf_zoom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/layout/mf_widget_place_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 | 35 | 36 | 48 | 49 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #0955ec 5 | #ff90c3 6 | #dc3983 7 | #33132836 8 | #c7cfd4 9 | #dde2e5 10 | #a9b1b5 11 | #95979a 12 | #535658 13 | #414346 14 | #212121 15 | #fafafa 16 | 17 | #33969696 18 | #40CBCBCB 19 | #3a3e43 20 | 21 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6dp 4 | 4dp 5 | 6 | 2dp 7 | 8 | 16dp 9 | 16dp 10 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android-sdk/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Mapfit Legal 3 | Build your map 4 | Place information window 5 | 6 | -------------------------------------------------------------------------------- /android-sdk/src/test/java/com/mapfit/android/GeocoderParserTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.geocoder.GeocodeParser 4 | import com.mapfit.android.geometry.isEmpty 5 | import org.junit.Assert 6 | import org.junit.Test 7 | 8 | /** 9 | * Created by dogangulcan on 1/22/18. 10 | */ 11 | class GeocoderParserTest { 12 | 13 | @Test 14 | fun parseResponse() { 15 | val parser = GeocodeParser() 16 | val addressList = parser.parseGeocodeResponse(response) 17 | 18 | Assert.assertTrue(addressList.isNotEmpty()) 19 | 20 | val firstAddress = addressList[0] 21 | 22 | Assert.assertTrue(firstAddress.streetAddress.isNotBlank()) 23 | Assert.assertTrue(firstAddress.adminArea.isNotBlank()) 24 | Assert.assertNotNull(firstAddress.responseType) 25 | Assert.assertTrue(firstAddress.locality.isNotBlank()) 26 | Assert.assertTrue(firstAddress.neighborhood.isNotBlank()) 27 | Assert.assertTrue(firstAddress.postalCode.isNotBlank()) 28 | Assert.assertEquals(0.0, firstAddress.lat, 0.0001) 29 | Assert.assertEquals(0.0, firstAddress.lng, 0.0001) 30 | Assert.assertTrue(firstAddress.postalCode.isNotBlank()) 31 | Assert.assertTrue(firstAddress.building.polygon.isNotEmpty()) 32 | Assert.assertFalse(firstAddress.viewport!!.southWest.isEmpty()) 33 | Assert.assertFalse(firstAddress.viewport!!.northEast.isEmpty()) 34 | 35 | val entrance = firstAddress.entrances[0] 36 | 37 | Assert.assertNotNull(entrance.entranceType) 38 | Assert.assertEquals(40.74405, entrance.lat, 0.0001) 39 | Assert.assertEquals(-73.99324, entrance.lng, 0.0001) 40 | 41 | } 42 | 43 | private val response = 44 | "[{ \"locality\": \"New York\", \"postal_code\": \"10011\", \"admin_1\": \"NY\", \"viewport\": { \"southwest\": { \"lon\": -73.97458, \"lat\": 40.6351 }, \"northeast\": { \"lon\": -73.92457999, \"lat\": 40.6651 } },\"country\" : \"USA\", \"neighborhood\": \"chelsea\", \"response_type\": 1, \"building\": { \"type\": \"Polygon\", \"coordinates\": [[[-73.992953, 40.744257], [-73.993265, 40.744389], [-73.993448, 40.744138], [-73.993136, 40.744006], [-73.992953, 40.744257]]] }, \"street_address\": \"119 W 24th St\", \"entrances\": [{ \"lon\": -73.99324, \"lat\": 40.74405, \"entrance_type\": \"pedestrian-primary\" }] }]" 45 | 46 | 47 | } -------------------------------------------------------------------------------- /android-sdk/src/test/java/com/mapfit/android/MapfitTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import android.content.Context 4 | import com.mapfit.android.exceptions.MapfitConfigurationException 5 | import junit.framework.Assert 6 | import org.junit.After 7 | import org.junit.Before 8 | import org.junit.Test 9 | import org.mockito.Mock 10 | import org.mockito.MockitoAnnotations 11 | 12 | /** 13 | * Created by dogangulcan on 1/19/18. 14 | */ 15 | class MapfitTest { 16 | 17 | @Mock 18 | lateinit var context: Context 19 | 20 | @Before 21 | fun init() { 22 | MockitoAnnotations.initMocks(this) 23 | Mapfit.dispose() 24 | } 25 | 26 | @After 27 | fun dispose() { 28 | Mapfit.dispose() 29 | } 30 | 31 | @Test(expected = MapfitConfigurationException::class) 32 | fun testNoApiKey() { 33 | Mapfit.getApiKey() 34 | } 35 | 36 | @Test 37 | fun testApiKey() { 38 | Mapfit.getInstance(context, "somerandomapikey") 39 | Assert.assertEquals("somerandomapikey", Mapfit.getApiKey()) 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /android-sdk/src/test/java/com/mapfit/android/UtilsTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android 2 | 3 | import com.mapfit.android.utils.isValidImageUrl 4 | import com.mapfit.android.utils.isValidZoomLevel 5 | import com.mapfit.android.utils.loadImageFromUrl 6 | import kotlinx.coroutines.experimental.runBlocking 7 | import org.junit.Assert 8 | import org.junit.Test 9 | 10 | /** 11 | * Unit tests for utils. 12 | * 13 | * Created by dogangulcan on 1/8/18. 14 | */ 15 | class UtilsTest { 16 | 17 | @Test 18 | fun testValidZoomLevel() { 19 | Assert.assertTrue(isValidZoomLevel(5f)) 20 | Assert.assertFalse(isValidZoomLevel(-5f)) 21 | Assert.assertFalse(isValidZoomLevel(26f)) 22 | } 23 | 24 | @Test 25 | fun testLoadImageFromUrl() { 26 | runBlocking { 27 | Assert.assertNull(loadImageFromUrl("https://www.google.com").await()) 28 | } 29 | } 30 | 31 | @Test 32 | fun testValidImageUrl() { 33 | Assert.assertFalse(isValidImageUrl("https://www.google.com")) 34 | Assert.assertFalse(isValidImageUrl("")) 35 | Assert.assertTrue(isValidImageUrl("https://mapfit.com/images/pngs/featuresGraphic.png")) 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /android-sdk/src/test/java/com/mapfit/android/geometry/LatLngBoundsTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geometry 2 | 3 | import junit.framework.Assert 4 | import org.junit.Before 5 | import org.junit.Test 6 | 7 | /** 8 | * Created by dogangulcan on 1/25/18. 9 | */ 10 | class LatLngBoundsTest { 11 | 12 | private lateinit var bounds: LatLngBounds 13 | 14 | @Before 15 | fun init() { 16 | val latLngList = listOf( 17 | LatLng(37.198504, -83.272133), 18 | LatLng(29.652243, -29.042111), 19 | LatLng(38.246623, -82.737144), 20 | LatLng(36.691771, -110.030517), 21 | LatLng(37.940202, -107.461721), 22 | LatLng(39.400789, -80.243273) 23 | ) 24 | 25 | val boundsBuilder = LatLngBounds.Builder() 26 | 27 | latLngList.forEach { 28 | boundsBuilder.include(it) 29 | } 30 | 31 | bounds = boundsBuilder.build() 32 | } 33 | 34 | @Test 35 | fun testSWandNE() { 36 | val expectedNE = LatLng(39.400789, -29.042111) 37 | val expectedSW = LatLng(29.652243, -110.030517) 38 | 39 | Assert.assertEquals(expectedNE, bounds.northEast) 40 | Assert.assertEquals(expectedSW, bounds.southWest) 41 | } 42 | 43 | @Test 44 | fun testZoomLevelAndCenter() { 45 | val expectedCenter = LatLng(42.09842441252814, -72.40426108071209) 46 | val expectedZoomLevel = 4.6440625f 47 | 48 | val viewWidth = 1440 49 | val viewHeight = 2194 50 | 51 | val (center, zoomLevel) = bounds.getVisibleBounds(viewWidth, viewHeight, 1f) 52 | 53 | Assert.assertEquals(expectedCenter.lat, center.lat, 0.00001) 54 | Assert.assertEquals(expectedCenter.lng, center.lng, 0.00001) 55 | Assert.assertEquals(expectedZoomLevel, zoomLevel) 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /android-sdk/src/test/java/com/mapfit/android/geometry/LatLngTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.android.geometry 2 | 3 | import org.junit.Assert 4 | import org.junit.Test 5 | 6 | /** 7 | * Unit tests fot [LatLng]. 8 | * 9 | * Created by dogangulcan on 1/8/18. 10 | */ 11 | class LatLngTest { 12 | 13 | @Test 14 | fun testValidLatLng() { 15 | // default 16 | val defaultLatlng = LatLng() 17 | Assert.assertEquals(0.0, defaultLatlng.lat + defaultLatlng.lng, 0.0) 18 | 19 | // valid input 20 | val validLatlng = LatLng(40.693825, -73.998691) 21 | Assert.assertEquals(40.693825, validLatlng.lat, 0.00001) 22 | Assert.assertEquals(-73.998691, validLatlng.lng, 0.00001) 23 | Assert.assertTrue(validLatlng.isValid()) 24 | 25 | // invalid input 26 | val invalidLatlng = LatLng(140.693825, -731.998691) 27 | Assert.assertFalse(invalidLatlng.isValid()) 28 | 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /android-sdk/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /assets/Android-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/assets/Android-banner.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | repositories { 4 | jcenter() 5 | maven { url "https://dl.bintray.com/kotlin/kotlin-eap/" } 6 | google() 7 | } 8 | 9 | ext.versions = [ 10 | 'kotlin' : '1.2.51', 11 | 'kotlin_coroutine' : '0.22.5', 12 | 'support_lib' : '27.1.1', 13 | 'okHttp' : '3.10.0', 14 | 'moshi' : '1.5.0', 15 | 'mockito' : '2.15.0', 16 | 'dokka' : '0.9.17', 17 | 'maven_gradle_plugin' : '2.1', 18 | 'bintray_release_plugin': '0.8.1' 19 | ] 20 | 21 | dependencies { 22 | classpath 'com.android.tools.build:gradle:3.1.3' 23 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" 24 | classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${versions.dokka}" 25 | classpath "com.github.dcendents:android-maven-gradle-plugin:${versions.maven_gradle_plugin}" 26 | classpath "com.novoda:bintray-release:${versions.bintray_release_plugin}" 27 | } 28 | 29 | } 30 | 31 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 32 | sourceCompatibility = JavaVersion.VERSION_1_8 33 | targetCompatibility = JavaVersion.VERSION_1_8 34 | 35 | kotlinOptions { 36 | jvmTarget = '1.8' 37 | apiVersion = '1.2' 38 | languageVersion = '1.2' 39 | } 40 | } 41 | 42 | allprojects { 43 | repositories { 44 | google() 45 | jcenter() 46 | mavenCentral() 47 | flatDir { 48 | dirs 'libs' 49 | } 50 | } 51 | 52 | tasks.withType(Javadoc).all { 53 | enabled = false 54 | } 55 | } 56 | 57 | apply from: file('gradle/dokka.gradle') 58 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/dokka.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Class reference documentation generator options. 3 | */ 4 | apply plugin: 'org.jetbrains.dokka-android' 5 | 6 | dokka { 7 | moduleName = 'mapfitsdk' 8 | outputFormat = 'html' 9 | outputDirectory = "$buildDir/mapfit-api-ref" 10 | 11 | sourceDirs = files('mapfitsdk/src/main/java/com') 12 | 13 | skipEmptyPackages = true 14 | 15 | linkMapping { 16 | // Source directory 17 | dir = "mapfitsdk/src/main/java/com" 18 | 19 | // URL showing where the source code can be accessed through the web browser 20 | url = "https://github.com/mapfit/android-sdk" 21 | 22 | // Suffix which is used to append the line number to the URL. Use #L for GitHub 23 | suffix = "#L" 24 | } 25 | } 26 | 27 | task deleteUnusedDokkaAssets(type: Delete) { 28 | file("$rootDir/mapfit-api-ref").listFiles().each { 29 | if (it.name.contains("android.R")) project.delete it 30 | if (it.name.contains("android.support")) project.delete it 31 | if (it.name.contains("com.google")) project.delete it 32 | if (it.name.contains("com.mapfit.mapfitsdk.utils")) project.delete it 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gradle/jcenter-push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.novoda.bintray-release' 2 | apply plugin: 'maven-publish' 3 | 4 | 5 | Properties properties = new Properties() 6 | properties.load(project.rootProject.file('mapfit_local.properties').newDataInputStream()) 7 | 8 | // config doc: https://github.com/novoda/bintray-release/wiki/Configuration-of-the-publish-closure 9 | publish { 10 | 11 | bintrayUser = properties.getProperty("bintray.user") 12 | bintrayKey = properties.getProperty("bintray.apikey") 13 | userOrg = 'mapfit' 14 | groupId = 'com.mapfit' 15 | artifactId = 'android-sdk' 16 | desc = "Mapfit Android SDK" 17 | publishVersion = project.mapfit.sdk_version 18 | website = 'https://github.com/mapfit/android-sdk' 19 | dryRun = false 20 | autoPublish = false 21 | 22 | } 23 | -------------------------------------------------------------------------------- /gradle/mapfit-tasks.gradle: -------------------------------------------------------------------------------- 1 | 2 | task assembleBintrayRelease(dependsOn: ['clean', 'build', 'assemble', 'generatePomFileForReleasePublication']) { 3 | group = 'mapfit' 4 | description = "Clean and assemble project artifacts" 5 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapfit/android-sdk/3d083d4fe426be61e23f756f654d6f90961624be/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 27 10:27:40 EDT 2018 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-4.4-all.zip 7 | -------------------------------------------------------------------------------- /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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 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 initFilterDrawer 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 initFilterDrawer 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 | :initFilterDrawer 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | .build 8 | /captures 9 | .externalNativeBuild 10 | /src/main/java/com/mapfit/demo/LabActivity.kt 11 | /src/main/java/com/mapfit/demo/LabJavaActivity.java 12 | /src/main/res/layout/activity_lab.xml 13 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 27 7 | buildToolsVersion '27.0.3' 8 | 9 | defaultConfig { 10 | applicationId "com.mapfit.mapfitdemo" 11 | minSdkVersion 16 12 | targetSdkVersion 27 13 | 14 | versionCode 2 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 18 | 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | } 28 | kotlin { 29 | experimental { 30 | coroutines "enable" 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(include: ['*.jar'], dir: 'libs') 36 | implementation "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}" 37 | implementation "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}" 38 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlin_coroutines}" 39 | implementation "com.android.support:appcompat-v7:${versions.support_lib}" 40 | implementation 'com.android.support.constraint:constraint-layout:1.1.2' 41 | implementation "com.android.support:support-v4:${versions.support_lib}" 42 | implementation "com.android.support:design:${versions.support_lib}" 43 | implementation 'com.google.code.gson:gson:2.8.2' 44 | 45 | testImplementation 'junit:junit:4.12' 46 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 47 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 48 | implementation project(':android-sdk') 49 | } 50 | -------------------------------------------------------------------------------- /sample/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 | -------------------------------------------------------------------------------- /sample/src/androidTest/java/com/mapfit/mapfitdemo/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.mapfitdemo 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.mapfit.mapfitdemo", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample/src/main/assets/dummy_coffee_shops.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "vendor0001", 4 | "title": "Coffee Shop 1", 5 | "address": "395 Flatbush Ave Extension, D, Brooklyn, NY 11201", 6 | "lat": 40.693825, 7 | "lng": -73.998691, 8 | "opensAt": "08:00", 9 | "closesAt": "22:00", 10 | "open24Hours": false 11 | }, 12 | { 13 | "id": "vendor0002", 14 | "title": "Coffee Shop 2", 15 | "address": "67 Front St, Brooklyn, NY 11201", 16 | "lat": 40.6902223, 17 | "lng": -73.9770368, 18 | "opensAt": "00:00", 19 | "closesAt": "00:00", 20 | "open24Hours": true 21 | }, 22 | { 23 | "id": "vendor0003", 24 | "title": "Coffee Shop 3", 25 | "address": "134 Montague St, Brooklyn, NY 11201", 26 | "lat": 40.6930532, 27 | "lng": -73.9860919, 28 | "opensAt": "10:00", 29 | "closesAt": "18:00", 30 | "open24Hours": false 31 | }, 32 | { 33 | "id": "vendor0004", 34 | "title": "Coffee Shop 4", 35 | "address": "135 John St, New York, NY 10038", 36 | "lat": 40.7061326, 37 | "lng": -74.000769, 38 | "opensAt": "08:00", 39 | "closesAt": "22:00", 40 | "open24Hours": false 41 | }, 42 | { 43 | "id": "vendor0005", 44 | "title": "Coffee Shop 5", 45 | "address": "55 Broad St, New York, NY 10004", 46 | "lat": 40.7170279, 47 | "lng": -74.0072867, 48 | "opensAt": "05:30", 49 | "closesAt": "22:00", 50 | "open24Hours": false 51 | }, 52 | { 53 | "id": "vendor0006", 54 | "title": "Coffee Shop 6", 55 | "address": "Lower Manhattan, New York, NY 10004", 56 | "lat": 40.703126, 57 | "lng": -74.015175, 58 | "opensAt": "00:00", 59 | "closesAt": "00:00", 60 | "open24Hours": true 61 | }, 62 | { 63 | "id": "vendor0007", 64 | "title": "Coffee Shop 7", 65 | "address": "Hoboken, New Jersey, NJ 07030", 66 | "lat": 40.743181, 67 | "lng": -74.026164, 68 | "opensAt": "10:00", 69 | "closesAt": "21:00", 70 | "open24Hours": false 71 | } 72 | ] -------------------------------------------------------------------------------- /sample/src/main/assets/sample.yaml: -------------------------------------------------------------------------------- 1 | # Mapfit Day Theme 2 | # Last updated Mar 19, 2018 3 | 4 | import: 5 | - sample-base-theme.yaml 6 | 7 | global: 8 | 9 | ####### ALL COLOR VARIABLES ####### 10 | 11 | # TEXT 12 | text_fill: rgba(90, 95, 105, 1) 13 | text_outline: rgba(255, 255, 255,.75) 14 | text_fill_neighborhoods: rgba(143, 156, 179, 1) 15 | text_fill_water: rgba(71, 123, 198, 1) 16 | text_outline_water: rgba(255, 255, 255,.75) 17 | text_fill_parks: rgba(67, 162, 84, 1) 18 | text_outline_parks: rgba(189, 222, 197, 1) 19 | text_beach_fill: rgba(153, 144, 92, 1) 20 | text_beach_outline: rgba(255, 255, 255,.75) 21 | text_highway_fill: rgba(109, 51, 4, 1) 22 | text_highway_outline: rgba(255, 255, 255,.75) 23 | text_highway_exits: rgba(237, 152, 6, 1) 24 | text_signs_fill: rgba(255, 255, 255, 1) 25 | 26 | # ROADS 27 | highway_fill: rgba(255, 224, 115, 1) 28 | highway_outline: rgba(255, 202, 112,1) 29 | road_fill: rgba(255, 255, 255,1) 30 | road_outline: rgba(223, 223, 223,1) 31 | tunnel_fill: rgba(223, 223, 223,1) 32 | tunnel_outline: rgba(223, 223, 223,1) 33 | road_directional_arrows_fill: rgba(240, 240, 240,1) 34 | pedestrian_path_fill: rgba(255, 255, 255,1) 35 | pedestrian_path_outline: rgba(255, 255, 255,1) 36 | pedestrian_steps_fill: rgba(242, 242, 242,1) 37 | roads_in_park_fill: rgba(189, 222, 197,1) 38 | roads_in_cemetary_fill: rgba(255, 255, 255,1) 39 | 40 | # WATER 41 | ocean_fill: rgba(137, 208, 255,1) 42 | water_fill: rgba(137, 208, 255,1) 43 | 44 | # LAND 45 | map_background_fill: rgba(255, 255, 255,1) 46 | land_fill: rgba(242, 242, 242,1) 47 | parks_fill: rgba(184, 233, 164,1) 48 | cemetary_fill: rgba(205, 238, 193,1) 49 | protected_area_fill: rgba(238, 237, 235,1) 50 | special_parks_fill: rgba(162, 223, 139,1) 51 | stadium_fill: rgba(191, 176, 142,1) 52 | playground_fill: rgba(215, 204, 176,1) 53 | beach_fill: rgba(235, 235, 201,1) 54 | military_fill: rgba(207, 209, 221,1) 55 | 56 | # BUILDINGS 57 | building_fill: rgba(235, 235, 235,1) 58 | building_outline: rgba(230, 230, 230,1) 59 | 60 | # AIRPORTS 61 | airport_road_fill: rgba(192, 195, 214,1) 62 | airport_land_fill: rgba(207, 209, 221,1) 63 | 64 | # EDUCATION 65 | university_fill: rgba(238, 227, 180,1) 66 | school_fill: rgba(242, 242, 242,1) 67 | 68 | # HOSPITALS 69 | hospital_fill: rgba(231, 204, 213,1) 70 | 71 | # FEATURES 72 | ferry_fill: rgba(124, 170, 203,1) 73 | railways_fill: rgba(223, 223, 223,1) 74 | special_pedestrian_area_fill: rgba(249, 246, 241,1) 75 | parking_fill: rgba(249, 246, 241,1) 76 | urbanization_fill: rgba(217, 196, 165,1) 77 | winter_sports_area_fill: rgba(236, 235, 232,1) 78 | tourism_area_fill: rgba(249, 246, 241,1) 79 | 80 | # BOUNDARIES 81 | region_boundary_fill: rgba(153, 153, 153,1) 82 | city_wall_fill: rgba(217, 196, 165,1) 83 | 84 | 85 | ####### ALL SHOW/HIDE VARIABLES ####### 86 | 87 | show_transit: false # public transit visibility 88 | show_3d_buildings: false # 3D building visibility 89 | show_special_areas: true # show commercial, retail, pedestrian areas 90 | show_parking_areas: true # show parking areas 91 | 92 | 93 | # CAMERA OPTIONS (IF 3D BUILDINGS ARE ON) 94 | 95 | cameras: 96 | master: 97 | type: perspective # choose between perspective, isometric, or flat 98 | 99 | textures: 100 | pois: 101 | url: https://cdn.mapfit.com/v2-2/themes/images/refill@2x.png 102 | -------------------------------------------------------------------------------- /sample/src/main/java/com/mapfit/demo/App.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.demo 2 | 3 | import android.app.Application 4 | import com.mapfit.android.Mapfit 5 | import com.mapfit.mapfitdemo.R 6 | 7 | class App : Application(){ 8 | 9 | override fun onCreate() { 10 | super.onCreate() 11 | Mapfit.getInstance(this, getString(R.string.mapfit_debug_api_key)) 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/mapfit/demo/CustomYamlActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.demo 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import com.mapfit.android.MapTheme 6 | import com.mapfit.android.MapfitMap 7 | import com.mapfit.android.OnMapReadyCallback 8 | import com.mapfit.android.OnMapThemeLoadListener 9 | import com.mapfit.mapfitdemo.R 10 | import kotlinx.android.synthetic.main.activity_main.* 11 | 12 | /** 13 | * This example demonstrates how you can implement your own yaml file. 14 | * You can use Mapfit paint tool to create your own style @see https://mapfit.com/paint/ 15 | * 16 | * Created by dogangulcan on 3/6/18. 17 | */ 18 | class CustomYamlActivity : AppCompatActivity() { 19 | 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | setContentView(R.layout.activity_main) 23 | 24 | mapView.getMapAsync( 25 | MapTheme.MAPFIT_GRAYSCALE, 26 | onMapReadyCallback = object : OnMapReadyCallback { 27 | override fun onMapReady(mapfitMap: MapfitMap) { 28 | setCustomTheme(mapfitMap) 29 | } 30 | }) 31 | 32 | } 33 | 34 | private fun setCustomTheme(mapfitMap: MapfitMap) { 35 | 36 | mapfitMap.setOnMapThemeLoadListener(object : OnMapThemeLoadListener { 37 | override fun onLoaded() { 38 | // called when the scene is loaded 39 | } 40 | 41 | override fun onError() { 42 | // called when there is an error while loading the scene 43 | } 44 | }) 45 | 46 | // you can provide a url or a file path here. if your yaml file is in assets folder, 47 | // just write the filename as the example, assets prefix will be added. 48 | mapfitMap.getMapOptions().customTheme = "sample.yaml" 49 | } 50 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/mapfit/demo/GeocoderActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.demo 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import com.mapfit.android.MapTheme 6 | import com.mapfit.android.MapView 7 | import com.mapfit.android.MapfitMap 8 | import com.mapfit.android.OnMapReadyCallback 9 | import com.mapfit.android.annotations.MarkerOptions 10 | import com.mapfit.android.annotations.PolygonOptions 11 | import com.mapfit.android.geocoder.Geocoder 12 | import com.mapfit.android.geocoder.GeocoderCallback 13 | import com.mapfit.android.geocoder.model.Address 14 | import com.mapfit.android.geometry.LatLng 15 | import com.mapfit.mapfitdemo.R 16 | 17 | class GeocoderActivity : AppCompatActivity() { 18 | 19 | lateinit var mapView: MapView 20 | lateinit var mapfitMap: MapfitMap 21 | 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | setContentView(R.layout.activity_main) 25 | 26 | mapView = findViewById(R.id.mapView) 27 | 28 | mapView.getMapAsync(MapTheme.MAPFIT_DAY, object : OnMapReadyCallback { 29 | override fun onMapReady(mapfitMap: MapfitMap) { 30 | setupMap(mapfitMap) 31 | } 32 | }) 33 | } 34 | 35 | private fun setupMap(mapfitMap: MapfitMap) { 36 | this.mapfitMap = mapfitMap 37 | 38 | mapfitMap.setCenter(LatLng(40.74405, -73.99324)) 39 | mapfitMap.setZoom(14f) 40 | 41 | geocodeAddress() 42 | reverseGeocodeAddress() 43 | } 44 | 45 | 46 | /** 47 | * Geocodes an address. 48 | */ 49 | private fun geocodeAddress() { 50 | Geocoder().geocode( 51 | "175 5th Ave, New York, NY 10010", 52 | true, 53 | object : GeocoderCallback { 54 | override fun onError(message: String, e: Exception) {} 55 | 56 | override fun onSuccess(addressList: List
) { 57 | var latLng = LatLng() 58 | addressList.forEach { address -> 59 | latLng = 60 | LatLng(address.entrances.first().lat, address.entrances.first().lng) 61 | } 62 | 63 | val marker = mapfitMap.addMarker(MarkerOptions().position(latLng)) 64 | val polygon = 65 | mapfitMap.addPolygon( 66 | PolygonOptions().points(addressList[0].building.polygon) 67 | ) 68 | } 69 | }) 70 | } 71 | 72 | /** 73 | * Reverse geocodes address of a [LatLng]. 74 | */ 75 | private fun reverseGeocodeAddress() { 76 | Geocoder().reverseGeocode( 77 | LatLng(40.74405, -73.99324), 78 | true, 79 | object : GeocoderCallback { 80 | override fun onError(message: String, e: Exception) {} 81 | 82 | override fun onSuccess(addressList: List
) { 83 | var latLng = LatLng() 84 | addressList.forEach { address -> 85 | latLng = 86 | LatLng(address.entrances.first().lat, address.entrances.first().lng) 87 | } 88 | 89 | val marker = mapfitMap.addMarker(MarkerOptions().position(latLng)) 90 | val polygon = 91 | mapfitMap.addPolygon( 92 | PolygonOptions().points(addressList[0].building.polygon) 93 | ) 94 | } 95 | }) 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /sample/src/main/java/com/mapfit/demo/KotlinActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.demo 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import com.mapfit.android.* 6 | import com.mapfit.android.annotations.MapfitMarker 7 | import com.mapfit.android.annotations.Marker 8 | import com.mapfit.android.annotations.MarkerOptions 9 | import com.mapfit.android.annotations.PolylineOptions 10 | import com.mapfit.android.annotations.callback.OnMarkerAddedCallback 11 | import com.mapfit.android.directions.Directions 12 | import com.mapfit.android.directions.DirectionsCallback 13 | import com.mapfit.android.directions.model.Route 14 | import com.mapfit.android.geometry.LatLng 15 | import com.mapfit.android.utils.decodePolyline 16 | import com.mapfit.mapfitdemo.R 17 | 18 | class KotlinActivity : AppCompatActivity() { 19 | 20 | lateinit var mapView: MapView 21 | lateinit var mapfitMap: MapfitMap 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContentView(R.layout.activity_main) 26 | 27 | mapView = findViewById(R.id.mapView) 28 | 29 | mapView.getMapAsync(MapTheme.MAPFIT_DAY, object : OnMapReadyCallback { 30 | override fun onMapReady(mapfitMap: MapfitMap) { 31 | setupMap(mapfitMap) 32 | } 33 | }) 34 | } 35 | 36 | private fun setupMap(mapfitMap: MapfitMap) { 37 | this.mapfitMap = mapfitMap 38 | 39 | mapfitMap.setCenter(LatLng(40.74405, -73.99324)) 40 | mapfitMap.setZoom(14f) 41 | mapfitMap.getMapOptions().isUserLocationButtonVisible = true 42 | 43 | placeMarker() 44 | placeMarkerWithAddress() 45 | getDirections() 46 | setEventListeners() 47 | 48 | // enable ui controls 49 | mapfitMap.getMapOptions().isRecenterButtonVisible = true 50 | mapfitMap.getMapOptions().isZoomControlVisible = true 51 | mapfitMap.getMapOptions().isCompassButtonVisible = true 52 | } 53 | 54 | private fun setEventListeners() { 55 | mapfitMap.setOnMapClickListener(object : OnMapClickListener { 56 | override fun onMapClicked(latLng: LatLng) { 57 | // map is clicked! 58 | } 59 | }) 60 | 61 | mapfitMap.setOnMapDoubleClickListener(object : OnMapDoubleClickListener { 62 | override fun onMapDoubleClicked(latLng: LatLng) { 63 | // map is double clicked! 64 | } 65 | }) 66 | 67 | } 68 | 69 | private fun placeMarker() { 70 | val position = LatLng(40.744023, -73.993150) 71 | val marker = mapfitMap.addMarker(MarkerOptions().position(position)) 72 | } 73 | 74 | private fun getDirections() { 75 | val originAddress = "111 Macdougal Street new york ny" 76 | val destinationAddress = "119 W 24th Street new york ny" 77 | 78 | Directions().route( 79 | originAddress, 80 | destinationAddress, 81 | callback = object : DirectionsCallback { 82 | 83 | override fun onSuccess(route: Route) { 84 | route.trip.legs.forEach { 85 | val leg = decodePolyline(it.shape) 86 | val polyline = mapfitMap.addPolyline(PolylineOptions().points(leg)) 87 | } 88 | } 89 | 90 | override fun onError(message: String, e: Exception) { 91 | 92 | } 93 | 94 | }) 95 | } 96 | 97 | private fun placeMarkerWithAddress() { 98 | val flatironBuildingAddress = "175 5th Ave, New York, NY 10010" 99 | 100 | val markerOptions = MarkerOptions() 101 | .streetAddress(flatironBuildingAddress) 102 | .addBuildingPolygon(true) 103 | .icon(MapfitMarker.EDUCATION) 104 | 105 | mapfitMap.addMarker( 106 | markerOptions, 107 | object : OnMarkerAddedCallback { 108 | override fun onMarkerAdded(marker: Marker) { 109 | // marker is added to the map! 110 | } 111 | 112 | override fun onError(exception: Exception) { 113 | // handle the exception 114 | } 115 | } 116 | ) 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /sample/src/main/java/com/mapfit/demo/UserLocationActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapfit.demo 2 | 3 | import android.Manifest 4 | import android.content.pm.PackageManager 5 | import android.os.Bundle 6 | import android.support.v4.content.ContextCompat 7 | import android.support.v7.app.AppCompatActivity 8 | import com.mapfit.android.MapTheme 9 | import com.mapfit.android.MapView 10 | import com.mapfit.android.MapfitMap 11 | import com.mapfit.android.OnMapReadyCallback 12 | import com.mapfit.mapfitdemo.R 13 | 14 | class UserLocationActivity : AppCompatActivity() { 15 | 16 | lateinit var mapView: MapView 17 | lateinit var mapfitMap: MapfitMap 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | setContentView(R.layout.activity_main) 22 | 23 | mapView = findViewById(R.id.mapView) 24 | 25 | mapView.getMapAsync(MapTheme.MAPFIT_DAY, object : OnMapReadyCallback { 26 | override fun onMapReady(mapfitMap: MapfitMap) { 27 | setupMap(mapfitMap) 28 | } 29 | }) 30 | } 31 | 32 | private fun setupMap(mapfitMap: MapfitMap) { 33 | this.mapfitMap = mapfitMap 34 | 35 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 36 | == PackageManager.PERMISSION_GRANTED 37 | ) { 38 | mapfitMap.getMapOptions().setUserLocationEnabled(true) 39 | } else { 40 | // location permission is not granted. You should user for location permission gracefully. 41 | } 42 | 43 | mapfitMap.getMapOptions().isUserLocationButtonVisible = true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_lab.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 15 | 16 |