diff options
author | Randall Lee <randall.lee@mapbox.com> | 2018-05-22 14:09:36 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-22 14:09:36 -0400 |
commit | d858cb783b499a1cc77b48a0faee137ca5e6a423 (patch) | |
tree | 5c36c353730e3050d44e472545519c0429723266 /platform/android | |
parent | f93d722458be62d567aa152711a014ef51a90193 (diff) | |
parent | 60505b03174b5ec02ae723beafa7683f6ed54a62 (diff) | |
download | qtlocation-mapboxgl-upstream/rclee-async-setup.tar.gz |
Merge branch 'master' into rclee-async-setupupstream/rclee-async-setup
Diffstat (limited to 'platform/android')
63 files changed, 1138 insertions, 665 deletions
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 246b5828c4..3fbfc32a76 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -2,6 +2,38 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. +## master +- Unknown tokens in URLs are now preserved, rather than replaced with an empty string [#11787](https://github.com/mapbox/mapbox-gl-native/issues/11787) + +## 6.1.2 - May 18, 2018 + - Update telemetry to 3.1.1 [#11942](https://github.com/mapbox/mapbox-gl-native/pull/11942) + +## 6.2.0-alpha.1 - May 17, 2018 + - `"to-string"` expression operator converts `null` to empty string rather than to `"null"` [#11904](https://github.com/mapbox/mapbox-gl-native/pull/11904) + - Expose MapView#setOfflineRegion [#1922](https://github.com/mapbox/mapbox-gl-native/pull/11922) + - Add nullability annotations to public API for kotlin language integration [#11925](https://github.com/mapbox/mapbox-gl-native/pull/11925) + - Expose MapView created callbacks on MapFragment and SupportMapFragment [#11934](https://github.com/mapbox/mapbox-gl-native/pull/11934) + - Update mapbox-java to 3.1.0 [#11916](https://github.com/mapbox/mapbox-gl-native/pull/11916) + +## 6.1.1 - May 7, 2018 + - Update telemetry to 3.1.0 [#11855](https://github.com/mapbox/mapbox-gl-native/pull/11855) + +## 6.1.0 - May 4, 2018 + - Unwrap LatLngBounds during JNI conversion [#11807](https://github.com/mapbox/mapbox-gl-native/pull/11807) + - Check if renderer is not destroyed before delivering snapshot [#11800](https://github.com/mapbox/mapbox-gl-native/pull/11800) + - Null-check source before removing [#11789](https://github.com/mapbox/mapbox-gl-native/pull/11789) + - Flutter support: promote pixel-ratio to public API NativeMapView [#11772](https://github.com/mapbox/mapbox-gl-native/pull/11772) + - Unwrap LatLngBounds for the shortest path when requesting camera [#11759](https://github.com/mapbox/mapbox-gl-native/pull/11759) + - Flutter support: integrate view callback abstraction [#11706](https://github.com/mapbox/mapbox-gl-native/pull/11706) + - Match expression doc tweaks [#11691](https://github.com/mapbox/mapbox-gl-native/pull/11691) + - Improve stop javadoc to include interpolate [#11677](https://github.com/mapbox/mapbox-gl-native/pull/11677) + - Reduce per-frame render CPU time [#11811](https://github.com/mapbox/mapbox-gl-native/issues/11811) + - Add Korean localization [#11792](https://github.com/mapbox/mapbox-gl-native/pull/11792) + - Add Danish localization; update Hungarian, Russian, Swedish translations [#11136](https://github.com/mapbox/mapbox-gl-native/pull/11136) + +## 5.5.3 - May 4, 2018 + - Check if renderer is not destroyed before delivering snapshot [#11800](https://github.com/mapbox/mapbox-gl-native/pull/11800) + ## 6.0.1 - April 17, 2018 - Bump telemetry version to 3.0.2 [#11710](https://github.com/mapbox/mapbox-gl-native/pull/11710) @@ -78,9 +110,9 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - Update javadoc configuration for Gradle 4.4 [#11384](https://github.com/mapbox/mapbox-gl-native/pull/11384) - Rework zoomIn and zoomOut to use ValueAnimators [#11382](https://github.com/mapbox/mapbox-gl-native/pull/11382) - Delete LocalRef when converting Image.java [#11350](https://github.com/mapbox/mapbox-gl-native/pull/11350) - - Use float for pixelratio when creating a snapshotter [#11367](https://github.com/mapbox/mapbox-gl-native/pull/11367) + - Use float for pixelratio when creating a snapshotter [#11367](https://github.com/mapbox/mapbox-gl-native/pull/11367) - Validate width/height when creating a snapshot [#11364](https://github.com/mapbox/mapbox-gl-native/pull/11364) - + ## 6.0.0-beta.3 - March 2, 2018 - Added missing local reference deletes [#11243](https://github.com/mapbox/mapbox-gl-native/pull/11243), [#11272](https://github.com/mapbox/mapbox-gl-native/pull/11272) - Remove obsolete camera api [#11201](https://github.com/mapbox/mapbox-gl-native/pull/11201) @@ -103,7 +135,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - Add missing DeleteLocalRefs [#11272](https://github.com/mapbox/mapbox-gl-native/pull/11272) - Continue loading style even if we mutate it [#11294](https://github.com/mapbox/mapbox-gl-native/pull/11294) - Update telemetry version for OkHttp [#11338](https://github.com/mapbox/mapbox-gl-native/pull/11338) - + ## 6.0.0-beta.2 - February 13, 2018 - Deprecate LocationEngine [#11185](https://github.com/mapbox/mapbox-gl-native/pull/11185) - Remove LOST from SDK [11186](https://github.com/mapbox/mapbox-gl-native/pull/11186) @@ -113,7 +145,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - AddImage performance improvement [#11111](https://github.com/mapbox/mapbox-gl-native/pull/11111) - Migrate MAS to 3.0.0, refactor GeoJson integration [#11149](https://github.com/mapbox/mapbox-gl-native/pull/11149) - Remove @jar and @aar dependency suffixes [#11161](https://github.com/mapbox/mapbox-gl-native/pull/11161) - + ## 5.4.1 - February 9, 2018 - Don't recreate TextureView surface as part of view resizing, solves OOM crashes [#11148](https://github.com/mapbox/mapbox-gl-native/pull/11148) - Don't invoke OnLowMemory before map is ready, solves startup crash on low memory devices [#11109](https://github.com/mapbox/mapbox-gl-native/pull/11109) @@ -148,7 +180,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - Custom library loader [#10733](https://github.com/mapbox/mapbox-gl-native/pull/10733) - Inconsistent parameters for LatLngBounds.union [#10728](https://github.com/mapbox/mapbox-gl-native/pull/10728) - Gradle 4.1 / AS 3.0 [#10549](https://github.com/mapbox/mapbox-gl-native/pull/10549) - + ## 5.3.2 - January 22, 2018 - Validate surface creation before destroying [#10890](https://github.com/mapbox/mapbox-gl-native/pull/10890) - Add filesource activation ot OfflineRegion [#10904](https://github.com/mapbox/mapbox-gl-native/pull/10904) @@ -158,7 +190,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - Allow changing the used OkHttpClient [#10948](https://github.com/mapbox/mapbox-gl-native/pull/10948) - Validate zoom level before creating telemetry event [#10959](https://github.com/mapbox/mapbox-gl-native/pull/10959) - Handle null call instances in HttpRequest [#10987](https://github.com/mapbox/mapbox-gl-native/pull/10987) - + ## 5.3.1 - January 10, 2018 - Blacklist binary program loading for Vivante GC4000 GPUs [#10862](https://github.com/mapbox/mapbox-gl-native/pull/10862) - Support Genymotion [#10841](https://github.com/mapbox/mapbox-gl-native/pull/10841) @@ -169,11 +201,11 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to - Allow configuring Http url logging when a request fails [#10830](https://github.com/mapbox/mapbox-gl-native/pull/10830) - Don't send double tap event multiple times for telemetry [#10854](https://github.com/mapbox/mapbox-gl-native/pull/10854) - Fix code generation [#10856](https://github.com/mapbox/mapbox-gl-native/pull/10856) - - Use the correct cancelable callback after posting cancel [#10871](https://github.com/mapbox/mapbox-gl-native/pull/10871) - + - Use the correct cancelable callback after posting cancel [#10871](https://github.com/mapbox/mapbox-gl-native/pull/10871) + ## 5.3.0 - December 20, 2017 - Add support for TinySDF [#10706](https://github.com/mapbox/mapbox-gl-native/pull/10706) - - Save restore MyLocationViewSettings [#10746](https://github.com/mapbox/mapbox-gl-native/pull/10746) + - Save restore MyLocationViewSettings [#10746](https://github.com/mapbox/mapbox-gl-native/pull/10746) - Post animation callback invocation [#10664](https://github.com/mapbox/mapbox-gl-native/pull/10664) - Allow configuring Http logging [#10681](https://github.com/mapbox/mapbox-gl-native/pull/10681) - Fix reverse scale gesture [#10688](https://github.com/mapbox/mapbox-gl-native/pull/10688) diff --git a/platform/android/MapboxGLAndroidSDK/.gitignore b/platform/android/MapboxGLAndroidSDK/.gitignore new file mode 100644 index 0000000000..c24bd2563a --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/.gitignore @@ -0,0 +1 @@ +dependency-graph-mapbox-libraries.png diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index f82968051d..21ed25e2c2 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -1,9 +1,13 @@ apply plugin: 'com.android.library' dependencies { - api dependenciesList.mapboxAndroidTelemetry + api (dependenciesList.mapboxAndroidTelemetry) { + exclude group: 'com.android.support', module: 'appcompat-v7' + } api dependenciesList.mapboxJavaGeoJSON - api dependenciesList.mapboxAndroidGestures + api (dependenciesList.mapboxAndroidGestures) { + exclude group: 'com.android.support', module: 'appcompat-v7' + } implementation dependenciesList.supportAnnotations implementation dependenciesList.supportFragmentV4 implementation dependenciesList.timber @@ -87,7 +91,7 @@ android { if (abi != 'all') { abiFilters abi.split(' ') } else { - abiFilters "armeabi", "armeabi-v7a", "mips", "x86", "arm64-v8a", "x86_64" + abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } } } @@ -111,7 +115,7 @@ android { } lintOptions { - disable 'MissingTranslation', 'TypographyQuotes', 'ObsoleteLintCustomCheck', 'MissingPermission' + disable 'MissingTranslation', 'TypographyQuotes', 'ObsoleteLintCustomCheck', 'MissingPermission', 'WrongThreadInterprocedural' checkAllWarnings true warningsAsErrors false } @@ -145,3 +149,4 @@ apply from: "${rootDir}/gradle/gradle-javadoc.gradle" apply from: "${rootDir}/gradle/gradle-publish.gradle" apply from: "${rootDir}/gradle/gradle-checkstyle.gradle" apply from: "${rootDir}/gradle/gradle-tests-staticblockremover.gradle" +apply from: "${rootDir}/gradle/gradle-dependencies-graph.gradle" diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties index bdfc444454..a49ef47674 100644 --- a/platform/android/MapboxGLAndroidSDK/gradle.properties +++ b/platform/android/MapboxGLAndroidSDK/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.mapbox.mapboxsdk -VERSION_NAME=6.1.0-SNAPSHOT +VERSION_NAME=6.2.0-SNAPSHOT POM_DESCRIPTION=Mapbox GL Android SDK POM_URL=https://github.com/mapbox/mapbox-gl-native diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java index 55494b72d8..c639e49013 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java @@ -28,7 +28,7 @@ public class LatLngBounds implements Parcelable { /** * Construct a new LatLngBounds based on its corners, given in NESW * order. - * + * <p> * If eastern longitude is smaller than the western one, bounds will include antimeridian. * For example, if the NE point is (10, -170) and the SW point is (-10, 170), then bounds will span over 20 degrees * and cross the antimeridian. @@ -75,7 +75,6 @@ public class LatLngBounds implements Parcelable { if (longCenter >= GeometryConstants.MAX_LONGITUDE) { longCenter = this.longitudeEast - halfSpan; } - return new LatLng(latCenter, longCenter); } return new LatLng(latCenter, longCenter); @@ -188,7 +187,6 @@ public class LatLngBounds implements Parcelable { return GeometryConstants.LONGITUDE_SPAN - longSpan; } - static double getLongitudeSpan(final double longEast, final double longWest) { double longSpan = Math.abs(longEast - longWest); if (longEast >= longWest) { @@ -240,6 +238,7 @@ public class LatLngBounds implements Parcelable { westLon = temp; } } else { + lonSpan = GeometryConstants.LONGITUDE_SPAN - lonSpan; if (westLon < eastLon) { double temp = eastLon; eastLon = westLon; @@ -278,12 +277,11 @@ public class LatLngBounds implements Parcelable { /** * Constructs a LatLngBounds from doubles representing a LatLng pair. - * + * <p> * This values of latNorth and latSouth should be in the range of [-90, 90], * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, * otherwise IllegalArgumentException will be thrown. * latNorth should be greater or equal latSouth, otherwise IllegalArgumentException will be thrown. - * * <p> * This method doesn't recalculate most east or most west boundaries. * Note that lonEast and lonWest will be wrapped to be in the range of [-180, 180], @@ -296,6 +294,20 @@ public class LatLngBounds implements Parcelable { @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, double lonWest) { + checkParams(latNorth, lonEast, latSouth, lonWest); + + lonEast = LatLng.wrap(lonEast, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + lonWest = LatLng.wrap(lonWest, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + + return new LatLngBounds(latNorth, lonEast, latSouth, lonWest); + } + + private static void checkParams( + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latNorth, + double lonEast, + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, + double lonWest) { + if (Double.isNaN(latNorth) || Double.isNaN(latSouth)) { throw new IllegalArgumentException("latitude must not be NaN"); } @@ -316,11 +328,6 @@ public class LatLngBounds implements Parcelable { if (latNorth < latSouth) { throw new IllegalArgumentException("LatSouth cannot be less than latNorth"); } - - lonEast = LatLng.wrap(lonEast, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - lonWest = LatLng.wrap(lonWest, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - - return new LatLngBounds(latNorth, lonEast, latSouth, lonWest); } private static double lat_(int z, int y) { @@ -334,14 +341,14 @@ public class LatLngBounds implements Parcelable { /** * Constructs a LatLngBounds from a Tile identifier. - * + * <p> * Returned bounds will have latitude in the range of Mercator projection. - * @see GeometryConstants#MIN_MERCATOR_LATITUDE - * @see GeometryConstants#MAX_MERCATOR_LATITUDE * * @param z Tile zoom level. * @param x Tile X coordinate. * @param y Tile Y coordinate. + * @see GeometryConstants#MIN_MERCATOR_LATITUDE + * @see GeometryConstants#MAX_MERCATOR_LATITUDE */ public static LatLngBounds from(int z, int x, int y) { return new LatLngBounds(lat_(z, y), lon_(z, x + 1), lat_(z, y + 1), lon_(z, x)); @@ -397,7 +404,7 @@ public class LatLngBounds implements Parcelable { return (longitude <= eastLon) && (longitude >= westLon); } - return (longitude < eastLon) || (longitude > westLon); + return (longitude <= eastLon) || (longitude >= westLon); } /** @@ -428,36 +435,94 @@ public class LatLngBounds implements Parcelable { * @param bounds LatLngBounds to add * @return LatLngBounds */ - public LatLngBounds union(LatLngBounds bounds) { - return union(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest()); + public @NonNull LatLngBounds union(@NonNull LatLngBounds bounds) { + return unionNoParamCheck(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest()); } /** * Returns a new LatLngBounds that stretches to include another LatLngBounds, * given by corner points. + * <p> + * This values of northLat and southLat should be in the range of [-90, 90], + * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, + * otherwise IllegalArgumentException will be thrown. + * northLat should be greater or equal southLat, otherwise IllegalArgumentException will be thrown. + * <p> + * This method doesn't recalculate most east or most west boundaries. + * Note that eastLon and westLon will be wrapped to be in the range of [-180, 180], + * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} * - * @param latNorth Northern Latitude - * @param lonEast Eastern Longitude - * @param latSouth Southern Latitude - * @param lonWest Western Longitude - * @return BoundingBox - */ - public LatLngBounds union(final double latNorth, final double lonEast, final double latSouth, final double lonWest) { - double north = (this.latitudeNorth < latNorth) ? latNorth : this.latitudeNorth; - double south = (this.latitudeSouth > latSouth) ? latSouth : this.latitudeSouth; - - if (LatLngSpan.getLongitudeSpan(lonEast, this.longitudeWest) - < LatLngSpan.getLongitudeSpan(this.longitudeEast, lonWest)) { - return new LatLngBounds(north, - lonEast, - south, + * @param northLat Northern Latitude corner point + * @param eastLon Eastern Longitude corner point + * @param southLat Southern Latitude corner point + * @param westLon Western Longitude corner point + * @return LatLngBounds + */ + public @NonNull LatLngBounds union( + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE)double northLat, + double eastLon, + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, + double westLon) { + + checkParams(northLat, eastLon, southLat, westLon); + + return unionNoParamCheck(northLat, eastLon, southLat, westLon); + } + + private @NonNull LatLngBounds unionNoParamCheck( + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE)double northLat, + double eastLon, + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, + double westLon) { + + northLat = (this.latitudeNorth < northLat) ? northLat : this.latitudeNorth; + southLat = (this.latitudeSouth > southLat) ? southLat : this.latitudeSouth; + + eastLon = LatLng.wrap(eastLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + westLon = LatLng.wrap(westLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + + // longitudes match + if (this.longitudeEast == eastLon && this.longitudeWest == westLon) { + return new LatLngBounds(northLat, eastLon, southLat, westLon); + } + + boolean eastInThis = containsLongitude(this.longitudeEast, this.longitudeWest, eastLon); + boolean westInThis = containsLongitude(this.longitudeEast, this.longitudeWest, westLon); + boolean thisEastInside = containsLongitude(eastLon, westLon, this.longitudeEast); + boolean thisWestInside = containsLongitude(eastLon, westLon, this.longitudeWest); + + // two intersections on each end - covers entire longitude + if (eastInThis && westInThis && thisEastInside && thisWestInside) { + return new LatLngBounds(northLat, GeometryConstants.MAX_LONGITUDE, southLat, GeometryConstants.MIN_LONGITUDE); + } + + if (eastInThis) { + if (westInThis) { + return new LatLngBounds(northLat, this.longitudeEast, southLat, this.longitudeWest); + } + return new LatLngBounds(northLat, this.longitudeEast, southLat, westLon); + } + + if (thisEastInside) { + if (thisWestInside) { + return new LatLngBounds(northLat, eastLon, southLat, westLon); + } + return new LatLngBounds(northLat, eastLon, southLat, this.longitudeWest); + } + + // bounds do not intersect, find where they will form shortest union + if (LatLngSpan.getLongitudeSpan(eastLon, this.longitudeWest) + < LatLngSpan.getLongitudeSpan(this.longitudeEast, westLon)) { + return new LatLngBounds(northLat, + eastLon, + southLat, this.longitudeWest); } - return new LatLngBounds(north, + return new LatLngBounds(northLat, this.longitudeEast, - south, - lonWest); + southLat, + westLon); } /** @@ -466,32 +531,89 @@ public class LatLngBounds implements Parcelable { * @param box LatLngBounds to intersect with * @return LatLngBounds */ - @Nullable - public LatLngBounds intersect(LatLngBounds box) { - double minLonWest = Math.max(getLonWest(), box.getLonWest()); - double maxLonEast = Math.min(getLonEast(), box.getLonEast()); - if (maxLonEast > minLonWest) { - double minLatSouth = Math.max(getLatSouth(), box.getLatSouth()); - double maxLatNorth = Math.min(getLatNorth(), box.getLatNorth()); - if (maxLatNorth > minLatSouth) { - return new LatLngBounds(maxLatNorth, maxLonEast, minLatSouth, minLonWest); - } - } - return null; + public @Nullable LatLngBounds intersect(@NonNull LatLngBounds box) { + return intersectNoParamCheck(box.getLatNorth(), box.getLonEast(), box.getLatSouth(), box.getLonWest()); } /** * Returns a new LatLngBounds that is the intersection of this with another LatLngBounds + * <p> + * This values of northLat and southLat should be in the range of [-90, 90], + * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, + * otherwise IllegalArgumentException will be thrown. + * northLat should be greater or equal southLat, otherwise IllegalArgumentException will be thrown. + * <p> + * This method doesn't recalculate most east or most west boundaries. + * Note that eastLon and westLon will be wrapped to be in the range of [-180, 180], + * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} * - * @param northLatitude Northern Longitude - * @param eastLongitude Eastern Latitude - * @param southLatitude Southern Longitude - * @param westLongitude Western Latitude + * @param northLat Northern Latitude corner point + * @param eastLon Eastern Longitude corner point + * @param southLat Southern Latitude corner point + * @param westLon Western Longitude corner point * @return LatLngBounds */ - public LatLngBounds intersect(double northLatitude, double eastLongitude, double southLatitude, - double westLongitude) { - return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude)); + public @Nullable LatLngBounds intersect( + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE)double northLat, + double eastLon, + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, + double westLon) { + + checkParams(northLat, eastLon, southLat, westLon); + + return intersectNoParamCheck(northLat, eastLon, southLat, westLon); + } + + private @Nullable LatLngBounds intersectNoParamCheck( + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE)double northLat, + double eastLon, + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, + double westLon) { + + double maxsouthLat = Math.max(getLatSouth(), Math.min(GeometryConstants.MAX_LATITUDE, southLat)); + double minnorthLat = Math.min(getLatNorth(), Math.max(GeometryConstants.MIN_LATITUDE, northLat)); + if (minnorthLat < maxsouthLat) { + return null; + } + + eastLon = LatLng.wrap(eastLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + westLon = LatLng.wrap(westLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); + + // longitudes match + if (this.longitudeEast == eastLon && this.longitudeWest == westLon) { + return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, westLon); + } + + boolean eastInThis = containsLongitude(this.longitudeEast, this.longitudeWest, eastLon); + boolean westInThis = containsLongitude(this.longitudeEast, this.longitudeWest, westLon); + boolean thisEastInside = containsLongitude(eastLon, westLon, this.longitudeEast); + boolean thisWestInside = containsLongitude(eastLon, westLon, this.longitudeWest); + + // two intersections : find the one that has longest span + if (eastInThis && westInThis && thisEastInside && thisWestInside) { + + if (getLongitudeSpan(eastLon, this.longitudeWest) > getLongitudeSpan(this.longitudeEast, westLon)) { + return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, this.longitudeWest); + } + + return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, westLon); + } + + if (eastInThis) { + if (westInThis) { + return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, westLon); + } + return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, this.longitudeWest); + } + + if (thisEastInside) { + if (thisWestInside) { + return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, this.longitudeWest); + } + return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, westLon); + } + + return null; } /** @@ -520,7 +642,7 @@ public class LatLngBounds implements Parcelable { return (int) ((latitudeNorth + 90) + ((latitudeSouth + 90) * 1000) + ((longitudeEast + 180) * 1000000) - + ((longitudeEast + 180) * 1000000000)); + + ((longitudeWest + 180) * 1000000000)); } /** @@ -548,11 +670,11 @@ public class LatLngBounds implements Parcelable { } private static LatLngBounds readFromParcel(final Parcel in) { - final double lonNorth = in.readDouble(); - final double latEast = in.readDouble(); - final double lonSouth = in.readDouble(); - final double latWest = in.readDouble(); - return new LatLngBounds(lonNorth, latEast, lonSouth, latWest); + final double northLat = in.readDouble(); + final double eastLon = in.readDouble(); + final double southLat = in.readDouble(); + final double westLon = in.readDouble(); + return new LatLngBounds(northLat, eastLon, southLat, westLon); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java index ab1191c0cc..d0e51f941f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk.http; - import android.content.Context; import android.content.pm.PackageInfo; import android.os.Build; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java index 5fcf206a5a..280877d61a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java @@ -8,7 +8,6 @@ import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import com.mapbox.mapboxsdk.utils.MapFragmentUtils; import java.util.ArrayList; @@ -31,6 +30,7 @@ import java.util.List; public final class MapFragment extends Fragment implements OnMapReadyCallback { private final List<OnMapReadyCallback> mapReadyCallbackList = new ArrayList<>(); + private OnMapViewReadyCallback mapViewReadyCallback; private MapboxMap mapboxMap; private MapView map; @@ -56,6 +56,19 @@ public final class MapFragment extends Fragment implements OnMapReadyCallback { } /** + * Called when the context attaches to this fragment. + * + * @param context the context attaching + */ + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnMapViewReadyCallback) { + mapViewReadyCallback = (OnMapViewReadyCallback) context; + } + } + + /** * Creates the fragment view hierarchy. * * @param inflater Inflater used to inflate content. @@ -75,15 +88,25 @@ public final class MapFragment extends Fragment implements OnMapReadyCallback { * Called when the fragment view hierarchy is created. * * @param view The content view of the fragment - * @param savedInstanceState THe saved instance state of the framgnt + * @param savedInstanceState The saved instance state of the fragment */ @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); map.onCreate(savedInstanceState); map.getMapAsync(this); + + // notify listeners about mapview creation + if (mapViewReadyCallback != null) { + mapViewReadyCallback.onMapViewReady(map); + } } + /** + * Called when the style of the map has successfully loaded. + * + * @param mapboxMap The public api controller of the map + */ @Override public void onMapReady(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; @@ -170,4 +193,21 @@ public final class MapFragment extends Fragment implements OnMapReadyCallback { onMapReadyCallback.onMapReady(mapboxMap); } } + + /** + * Callback to be invoked when the map fragment has inflated its MapView. + * <p> + * To use this interface the context hosting the fragment must implement this interface. + * That instance will be set as part of Fragment#onAttach(Context context). + * </p> + */ + public interface OnMapViewReadyCallback { + + /** + * Called when the map has been created. + * + * @param mapView The created mapview + */ + void onMapViewReady(MapView mapView); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 4ecd7c9246..0f19965224 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -23,7 +23,6 @@ import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ZoomButtonsController; - import com.mapbox.android.gestures.AndroidGesturesManager; import com.mapbox.android.telemetry.AppUserTurnstile; import com.mapbox.android.telemetry.Event; @@ -33,6 +32,8 @@ import com.mapbox.mapboxsdk.BuildConfig; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.annotations.Annotation; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.maps.renderer.MapRenderer; @@ -40,9 +41,13 @@ import com.mapbox.mapboxsdk.maps.renderer.glsurfaceview.GLSurfaceViewMapRenderer import com.mapbox.mapboxsdk.maps.renderer.textureview.TextureViewMapRenderer; import com.mapbox.mapboxsdk.maps.widgets.CompassView; import com.mapbox.mapboxsdk.net.ConnectivityReceiver; +import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition; +import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.utils.BitmapUtils; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -51,9 +56,6 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; - import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_MAP_NORTH_ANIMATION; import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_WAIT_IDLE; @@ -96,28 +98,30 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { @UiThread public MapView(@NonNull Context context) { super(context); - initialise(context, MapboxMapOptions.createFromAttributes(context, null)); + initialize(context, MapboxMapOptions.createFromAttributes(context, null)); } @UiThread public MapView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); - initialise(context, MapboxMapOptions.createFromAttributes(context, attrs)); + initialize(context, MapboxMapOptions.createFromAttributes(context, attrs)); } @UiThread public MapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - initialise(context, MapboxMapOptions.createFromAttributes(context, attrs)); + initialize(context, MapboxMapOptions.createFromAttributes(context, attrs)); } @UiThread public MapView(@NonNull Context context, @Nullable MapboxMapOptions options) { super(context); - initialise(context, options == null ? MapboxMapOptions.createFromAttributes(context, null) : options); + initialize(context, options == null ? MapboxMapOptions.createFromAttributes(context, null) : options); } - private void initialise(@NonNull final Context context, @NonNull final MapboxMapOptions options) { + @CallSuper + @UiThread + protected void initialize(@NonNull final Context context, @NonNull final MapboxMapOptions options) { if (isInEditMode()) { // in IDE layout editor, just return return; @@ -535,6 +539,35 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { nativeMapView.setStyleUrl(url); } + /** + * Loads a new style from the specified offline region definition and moves the map camera to that region. + * + * @param definition the offline region definition + * @see OfflineRegionDefinition + */ + public void setOfflineRegionDefinition(OfflineRegionDefinition definition) { + if (destroyed) { + return; + } + + OfflineTilePyramidRegionDefinition regionDefinition = (OfflineTilePyramidRegionDefinition) definition; + setStyleUrl(regionDefinition.getStyleURL()); + CameraPosition cameraPosition = new CameraPosition.Builder() + .target(regionDefinition.getBounds().getCenter()) + .zoom(regionDefinition.getMinZoom()) + .build(); + + if (!isMapInitialized()) { + mapboxMapOptions.camera(cameraPosition); + mapboxMapOptions.minZoomPreference(regionDefinition.getMinZoom()); + mapboxMapOptions.maxZoomPreference(regionDefinition.getMaxZoom()); + return; + } + mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + mapboxMap.setMinZoomPreference(regionDefinition.getMinZoom()); + mapboxMap.setMaxZoomPreference(regionDefinition.getMaxZoom()); + } + // // Rendering // @@ -598,10 +631,8 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { * @param listener The callback that's invoked on every frame rendered to the map view. * @see MapView#removeOnMapChangedListener(OnMapChangedListener) */ - public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) { - if (listener != null) { - onMapChangedListeners.add(listener); - } + public void addOnMapChangedListener(@NonNull OnMapChangedListener listener) { + onMapChangedListeners.add(listener); } /** @@ -610,8 +641,8 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { * @param listener The previously added callback to remove. * @see MapView#addOnMapChangedListener(OnMapChangedListener) */ - public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) { - if (listener != null && onMapChangedListeners.contains(listener)) { + public void removeOnMapChangedListener(@NonNull OnMapChangedListener listener) { + if (onMapChangedListeners.contains(listener)) { onMapChangedListeners.remove(listener); } } @@ -622,13 +653,11 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { * @param callback The callback object that will be triggered when the map is ready to be used. */ @UiThread - public void getMapAsync(final OnMapReadyCallback callback) { - if (!mapCallback.isInitialLoad() && callback != null) { + public void getMapAsync(final @NonNull OnMapReadyCallback callback) { + if (!mapCallback.isInitialLoad()) { callback.onMapReady(mapboxMap); } else { - if (callback != null) { - mapCallback.addOnMapReadyCallback(callback); - } + mapCallback.addOnMapReadyCallback(callback); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 5e36dd0f78..aed918cb79 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -120,7 +120,7 @@ public final class MapboxMap { * * @param outState the bundle to save the state to. */ - void onSaveInstanceState(Bundle outState) { + void onSaveInstanceState(@NonNull Bundle outState) { outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, transform.getCameraPosition()); outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, nativeMapView.getDebug()); outState.putString(MapboxConstants.STATE_STYLE_URL, nativeMapView.getStyleUrl()); @@ -132,7 +132,7 @@ public final class MapboxMap { * * @param savedInstanceState the bundle containing the saved state */ - void onRestoreInstanceState(Bundle savedInstanceState) { + void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { final CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION); uiSettings.onRestoreInstanceState(savedInstanceState); @@ -266,6 +266,7 @@ public final class MapboxMap { * * @return all the layers in the current style */ + @NonNull public List<Layer> getLayers() { return nativeMapView.getLayers(); } @@ -377,6 +378,7 @@ public final class MapboxMap { * * @return all the sources in the current style */ + @NonNull public List<Source> getSources() { return nativeMapView.getSources(); } @@ -463,10 +465,11 @@ public final class MapboxMap { * * @param name the name of the image to remove */ - public void removeImage(String name) { + public void removeImage(@NonNull String name) { nativeMapView.removeImage(name); } + @Nullable public Bitmap getImage(@NonNull String name) { return nativeMapView.getImage(name); } @@ -537,6 +540,7 @@ public final class MapboxMap { * * @return the UiSettings associated with this map */ + @NonNull public UiSettings getUiSettings() { return uiSettings; } @@ -551,6 +555,7 @@ public final class MapboxMap { * * @return the Projection associated with this map */ + @NonNull public Projection getProjection() { return projection; } @@ -564,7 +569,7 @@ public final class MapboxMap { * * @return the global light source */ - @Nullable + @NonNull public Light getLight() { return nativeMapView.getLight(); } @@ -590,6 +595,7 @@ public final class MapboxMap { * * @return The current position of the Camera. */ + @NonNull public final CameraPosition getCameraPosition() { return transform.getCameraPosition(); } @@ -612,7 +618,7 @@ public final class MapboxMap { * * @param update The change that should be applied to the camera. */ - public final void moveCamera(CameraUpdate update) { + public final void moveCamera(@NonNull CameraUpdate update) { moveCamera(update, null); } @@ -624,7 +630,8 @@ public final class MapboxMap { * @param update The change that should be applied to the camera * @param callback the callback to be invoked when an animation finishes or is canceled */ - public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) { + public final void moveCamera(@NonNull final CameraUpdate update, + @Nullable final MapboxMap.CancelableCallback callback) { transform.moveCamera(MapboxMap.this, update, callback); } @@ -650,7 +657,7 @@ public final class MapboxMap { * positive, otherwise an IllegalArgumentException will be thrown. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void easeCamera(CameraUpdate update, int durationMs) { + public final void easeCamera(@NonNull CameraUpdate update, int durationMs) { easeCamera(update, durationMs, null); } @@ -673,7 +680,8 @@ public final class MapboxMap { * Do not update or ease the camera from within onCancel(). * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { + public final void easeCamera(@NonNull CameraUpdate update, int durationMs, + @Nullable final MapboxMap.CancelableCallback callback) { easeCamera(update, durationMs, true, callback); } @@ -691,7 +699,7 @@ public final class MapboxMap { * positive, otherwise an IllegalArgumentException will be thrown. * @param easingInterpolator True for easing interpolator, false for linear. */ - public final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator) { + public final void easeCamera(@NonNull CameraUpdate update, int durationMs, boolean easingInterpolator) { easeCamera(update, durationMs, easingInterpolator, null); } @@ -711,8 +719,10 @@ public final class MapboxMap { * by a later camera movement or a user gesture, onCancel() will be called. * Do not update or ease the camera from within onCancel(). */ - public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, - final MapboxMap.CancelableCallback callback) { + public final void easeCamera(@NonNull final CameraUpdate update, + final int durationMs, + final boolean easingInterpolator, + @Nullable final MapboxMap.CancelableCallback callback) { easeCamera(update, durationMs, easingInterpolator, callback, false); } @@ -733,8 +743,9 @@ public final class MapboxMap { * Do not update or ease the camera from within onCancel(). * @param isDismissable true will allow animated camera changes dismiss a tracking mode. */ - public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, - final MapboxMap.CancelableCallback callback, final boolean isDismissable) { + public final void easeCamera(@NonNull final CameraUpdate update, final int durationMs, + final boolean easingInterpolator, @Nullable final MapboxMap.CancelableCallback callback, + final boolean isDismissable) { if (durationMs <= 0) { throw new IllegalArgumentException("Null duration passed into easeCamera"); @@ -751,7 +762,7 @@ public final class MapboxMap { * @param update The change that should be applied to the camera. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void animateCamera(CameraUpdate update) { + public final void animateCamera(@NonNull CameraUpdate update) { animateCamera(update, MapboxConstants.ANIMATION_DURATION, null); } @@ -767,7 +778,7 @@ public final class MapboxMap { * called. Do not update or animate the camera from within onCancel(). * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) { + public final void animateCamera(@NonNull CameraUpdate update, @Nullable MapboxMap.CancelableCallback callback) { animateCamera(update, MapboxConstants.ANIMATION_DURATION, callback); } @@ -782,7 +793,7 @@ public final class MapboxMap { * positive, otherwise an IllegalArgumentException will be thrown. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void animateCamera(CameraUpdate update, int durationMs) { + public final void animateCamera(@NonNull CameraUpdate update, int durationMs) { animateCamera(update, durationMs, null); } @@ -804,8 +815,8 @@ public final class MapboxMap { * isn't required, leave it as null. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ - public final void animateCamera(final CameraUpdate update, final int durationMs, - final MapboxMap.CancelableCallback callback) { + public final void animateCamera(@NonNull final CameraUpdate update, final int durationMs, + @Nullable final MapboxMap.CancelableCallback callback) { if (durationMs <= 0) { throw new IllegalArgumentException("Null duration passed into animageCamera"); } @@ -1069,6 +1080,7 @@ public final class MapboxMap { * * @return The json of the map style */ + @NonNull public String getStyleJson() { return nativeMapView.getStyleJson(); } @@ -1232,7 +1244,7 @@ public final class MapboxMap { * * @param polyline An updated polyline object. */ - public void updatePolyline(Polyline polyline) { + public void updatePolyline(@NonNull Polyline polyline) { annotationManager.updatePolyline(polyline); } @@ -1263,7 +1275,7 @@ public final class MapboxMap { * * @param polygon An updated polygon object */ - public void updatePolygon(Polygon polygon) { + public void updatePolygon(@NonNull Polygon polygon) { annotationManager.updatePolygon(polygon); } @@ -1468,6 +1480,7 @@ public final class MapboxMap { * * @return The currently selected marker. */ + @NonNull public List<Marker> getSelectedMarkers() { return annotationManager.getSelectedMarkers(); } @@ -1477,6 +1490,7 @@ public final class MapboxMap { * * @return the associated MarkerViewManager */ + @NonNull public MarkerViewManager getMarkerViewManager() { return annotationManager.getMarkerViewManager(); } @@ -1550,7 +1564,8 @@ public final class MapboxMap { * @param padding the padding to apply to the bounds * @return the camera position that fits the bounds and padding */ - public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBounds, int[] padding) { + @NonNull + public CameraPosition getCameraForLatLngBounds(@NonNull LatLngBounds latLngBounds, int[] padding) { // get padded camera position from LatLngBounds return nativeMapView.getCameraForLatLngBounds(latLngBounds, padding); } @@ -1563,6 +1578,7 @@ public final class MapboxMap { * @param padding the padding to apply to the bounds * @return the camera position that fits the bounds and padding */ + @NonNull public CameraPosition getCameraForGeometry(Geometry geometry, double bearing, int[] padding) { // get padded camera position from Geometry return nativeMapView.getCameraForGeometry(geometry, bearing, padding); @@ -1591,11 +1607,7 @@ public final class MapboxMap { * @param bottom The bottom margin in pixels. */ public void setPadding(int left, int top, int right, int bottom) { - setPadding(new int[] {left, top, right, bottom}); - } - - private void setPadding(int[] padding) { - projection.setContentPadding(padding); + projection.setContentPadding(new int[] {left, top, right, bottom}); uiSettings.invalidate(); } @@ -1604,6 +1616,7 @@ public final class MapboxMap { * * @return An array with length 4 in the LTRB order. */ + @NonNull public int[] getPadding() { return projection.getContentPadding(); } @@ -1755,6 +1768,7 @@ public final class MapboxMap { } // used by MapView + @Nullable OnFpsChangedListener getOnFpsChangedListener() { return onFpsChangedListener; } @@ -1902,7 +1916,7 @@ public final class MapboxMap { * will be added to the passed gestures manager. * @see <a href="https://github.com/mapbox/mapbox-gestures-android">mapbox-gestures-android library</a> */ - public void setGesturesManager(AndroidGesturesManager androidGesturesManager, boolean attachDefaultListeners, + public void setGesturesManager(@NonNull AndroidGesturesManager androidGesturesManager, boolean attachDefaultListeners, boolean setDefaultMutuallyExclusives) { onGesturesManagerInteractionListener.setGesturesManager( androidGesturesManager, attachDefaultListeners, setDefaultMutuallyExclusives); @@ -1914,6 +1928,7 @@ public final class MapboxMap { * * @return Current gestures manager. */ + @NonNull public AndroidGesturesManager getGesturesManager() { return onGesturesManagerInteractionListener.getGesturesManager(); } @@ -2000,6 +2015,7 @@ public final class MapboxMap { * * @return Current active InfoWindow Click Listener */ + @Nullable public OnInfoWindowClickListener getOnInfoWindowClickListener() { return annotationManager.getInfoWindowManager().getOnInfoWindowClickListener(); } @@ -2020,6 +2036,7 @@ public final class MapboxMap { * * @return Current active InfoWindow long Click Listener */ + @Nullable public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() { return annotationManager.getInfoWindowManager().getOnInfoWindowLongClickListener(); } @@ -2038,6 +2055,7 @@ public final class MapboxMap { * * @return Current active InfoWindow Close Listener */ + @Nullable public OnInfoWindowCloseListener getOnInfoWindowCloseListener() { return annotationManager.getInfoWindowManager().getOnInfoWindowCloseListener(); } @@ -2147,11 +2165,11 @@ public final class MapboxMap { * @see MapboxMap#addOnMoveListener(OnMoveListener) */ public interface OnMoveListener { - void onMoveBegin(MoveGestureDetector detector); + void onMoveBegin(@NonNull MoveGestureDetector detector); - void onMove(MoveGestureDetector detector); + void onMove(@NonNull MoveGestureDetector detector); - void onMoveEnd(MoveGestureDetector detector); + void onMoveEnd(@NonNull MoveGestureDetector detector); } /** @@ -2160,11 +2178,11 @@ public final class MapboxMap { * @see MapboxMap#addOnRotateListener(OnRotateListener) */ public interface OnRotateListener { - void onRotateBegin(RotateGestureDetector detector); + void onRotateBegin(@NonNull RotateGestureDetector detector); - void onRotate(RotateGestureDetector detector); + void onRotate(@NonNull RotateGestureDetector detector); - void onRotateEnd(RotateGestureDetector detector); + void onRotateEnd(@NonNull RotateGestureDetector detector); } /** @@ -2173,11 +2191,11 @@ public final class MapboxMap { * @see MapboxMap#addOnScaleListener(OnScaleListener) */ public interface OnScaleListener { - void onScaleBegin(StandardScaleGestureDetector detector); + void onScaleBegin(@NonNull StandardScaleGestureDetector detector); - void onScale(StandardScaleGestureDetector detector); + void onScale(@NonNull StandardScaleGestureDetector detector); - void onScaleEnd(StandardScaleGestureDetector detector); + void onScaleEnd(@NonNull StandardScaleGestureDetector detector); } /** @@ -2186,11 +2204,11 @@ public final class MapboxMap { * @see MapboxMap#addOnShoveListener(OnShoveListener) */ public interface OnShoveListener { - void onShoveBegin(ShoveGestureDetector detector); + void onShoveBegin(@NonNull ShoveGestureDetector detector); - void onShove(ShoveGestureDetector detector); + void onShove(@NonNull ShoveGestureDetector detector); - void onShoveEnd(ShoveGestureDetector detector); + void onShoveEnd(@NonNull ShoveGestureDetector detector); } /** @@ -2442,7 +2460,7 @@ public final class MapboxMap { * * @param marker The marker were the info window is attached to */ - void onInfoWindowLongClick(Marker marker); + void onInfoWindowLongClick(@NonNull Marker marker); } /** @@ -2457,7 +2475,7 @@ public final class MapboxMap { * * @param marker The marker of the info window that was closed. */ - void onInfoWindowClose(Marker marker); + void onInfoWindowClose(@NonNull Marker marker); } /** @@ -2637,7 +2655,7 @@ public final class MapboxMap { * * @param snapshot the snapshot bitmap */ - void onSnapshotReady(Bitmap snapshot); + void onSnapshotReady(@NonNull Bitmap snapshot); } /** @@ -2649,12 +2667,13 @@ public final class MapboxMap { * * @param style the style that has been loaded */ - void onStyleLoaded(String style); + void onStyleLoaded(@NonNull String style); } // // Used for instrumentation testing // + @NonNull Transform getTransform() { return transform; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index b2d7af7687..d258064908 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -759,9 +759,13 @@ final class NativeMapView { return null; } Source source = getSource(sourceId); - return removeSource(source); + if (source != null) { + return removeSource(source); + } + return null; } + @Nullable public Source removeSource(@NonNull Source source) { if (isDestroyedOn("removeSource")) { return null; @@ -775,8 +779,9 @@ final class NativeMapView { return; } - // Determine pixel ratio - nativeAddImage(name, image, image.getDensity() / DisplayMetrics.DENSITY_DEFAULT); + // Determine pixel ratio, cast to float to avoid rounding, see mapbox-gl-native/issues/11809 + float pixelRatio = (float) image.getDensity() / DisplayMetrics.DENSITY_DEFAULT; + nativeAddImage(name, image, pixelRatio); } public void addImages(@NonNull HashMap<String, Bitmap> bitmapHashMap) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java index f35355533d..d5166c17b0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -43,14 +43,16 @@ public class Projection { /** * Returns the spherical Mercator projected meters for a LatLng. */ - public ProjectedMeters getProjectedMetersForLatLng(LatLng latLng) { + @NonNull + public ProjectedMeters getProjectedMetersForLatLng(@NonNull LatLng latLng) { return nativeMapView.projectedMetersForLatLng(latLng); } /** * Returns the LatLng for a spherical Mercator projected meters. */ - public LatLng getLatLngForProjectedMeters(ProjectedMeters projectedMeters) { + @NonNull + public LatLng getLatLngForProjectedMeters(@NonNull ProjectedMeters projectedMeters) { return nativeMapView.latLngForProjectedMeters(projectedMeters); } @@ -77,7 +79,8 @@ public class Projection { * @return The LatLng corresponding to the point on the screen, or null if the ray through * the given screen point does not intersect the ground plane. */ - public LatLng fromScreenLocation(PointF point) { + @NonNull + public LatLng fromScreenLocation(@NonNull PointF point) { return nativeMapView.latLngForPixel(point); } @@ -87,6 +90,7 @@ public class Projection { * * @return The projection of the viewing frustum in its current state. */ + @NonNull public VisibleRegion getVisibleRegion() { float left = 0; float right = nativeMapView.getWidth(); @@ -151,7 +155,8 @@ public class Projection { * @param location A LatLng on the map to convert to a screen location. * @return A Point representing the screen location in screen pixels. */ - public PointF toScreenLocation(LatLng location) { + @NonNull + public PointF toScreenLocation(@NonNull LatLng location) { return nativeMapView.pixelForLatLng(location); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java index 8aa4c7fd09..307b33b0c7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java @@ -31,6 +31,7 @@ import java.util.List; public class SupportMapFragment extends Fragment implements OnMapReadyCallback { private final List<OnMapReadyCallback> mapReadyCallbackList = new ArrayList<>(); + private MapFragment.OnMapViewReadyCallback mapViewReadyCallback; private MapboxMap mapboxMap; private MapView map; @@ -56,6 +57,19 @@ public class SupportMapFragment extends Fragment implements OnMapReadyCallback { } /** + * Called when the context attaches to this fragment. + * + * @param context the context attaching + */ + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof MapFragment.OnMapViewReadyCallback) { + mapViewReadyCallback = (MapFragment.OnMapViewReadyCallback) context; + } + } + + /** * Creates the fragment view hierarchy. * * @param inflater Inflater used to inflate content. @@ -82,6 +96,11 @@ public class SupportMapFragment extends Fragment implements OnMapReadyCallback { super.onViewCreated(view, savedInstanceState); map.onCreate(savedInstanceState); map.getMapAsync(this); + + // notify listeners about MapView creation + if (mapViewReadyCallback != null) { + mapViewReadyCallback.onMapViewReady(map); + } } @Override diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java index c1daebbe52..100787fbf0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java @@ -332,7 +332,7 @@ public final class UiSettings { * * @param compass the drawable to show as image compass */ - public void setCompassImage(Drawable compass) { + public void setCompassImage(@NonNull Drawable compass) { compassView.setCompassImage(compass); } @@ -409,6 +409,7 @@ public final class UiSettings { * * @return the drawable used as compass image */ + @NonNull public Drawable getCompassImage() { return compassView.getCompassImage(); } @@ -544,7 +545,7 @@ public final class UiSettings { * * @param attributionDialogManager the manager class used for showing attribution */ - public void setAttributionDialogManager(AttributionDialogManager attributionDialogManager) { + public void setAttributionDialogManager(@NonNull AttributionDialogManager attributionDialogManager) { this.attributionDialogManager = attributionDialogManager; } @@ -553,6 +554,7 @@ public final class UiSettings { * * @return the active manager class used for showing attribution */ + @NonNull public AttributionDialogManager getAttributionDialogManager() { return attributionDialogManager; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java index f1c70325a0..fcee5bd179 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java @@ -37,11 +37,11 @@ public abstract class MapRenderer implements MapRendererScheduler { } public void onPause() { - nativeOnPause(); + // Implement if needed } public void onResume() { - nativeOnResume(); + // Implement if needed } public void onStop() { @@ -124,10 +124,6 @@ public abstract class MapRenderer implements MapRendererScheduler { private native void nativeRender(); - private native void nativeOnResume(); - - private native void nativeOnPause(); - private long frames; private long timeElapsed; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java index f0cb8d973a..929e4b4279 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java @@ -6,6 +6,8 @@ import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.os.Environment; import android.support.annotation.NonNull; +import android.support.annotation.UiThread; + import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; import timber.log.Timber; @@ -43,6 +45,7 @@ public class FileSource { * @param context the context to derive the cache path from * @return the single instance of FileSource */ + @UiThread public static synchronized FileSource getInstance(Context context) { if (INSTANCE == null) { String cachePath = getCachePath(context); @@ -122,6 +125,8 @@ public class FileSource { initialize(Mapbox.getAccessToken(), cachePath, assetManager); } + public native boolean isActivated(); + public native void activate(); public native void deactivate(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 4289deeda3..1dd8eddab9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -166,7 +166,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param value a String value * @return property wrapper around String @@ -176,7 +176,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -356,7 +356,7 @@ public class PropertyFactory { } /** - * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. + * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. Note that GeoJSON sources with `lineMetrics: true` specified won't render dashed lines to the expected scale. Also note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param value a Float[] value * @return property wrapper around Float[] @@ -366,7 +366,7 @@ public class PropertyFactory { } /** - * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. + * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. Note that GeoJSON sources with `lineMetrics: true` specified won't render dashed lines to the expected scale. Also note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -376,7 +376,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param value a String value * @return property wrapper around String @@ -386,7 +386,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -1156,7 +1156,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing images on extruded fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing images on extruded fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param value a String value * @return property wrapper around String @@ -1166,7 +1166,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing images on extruded fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing images on extruded fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -1536,7 +1536,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param value a String value * @return property wrapper around String @@ -1546,7 +1546,7 @@ public class PropertyFactory { } /** - * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels. * * @param expression an expression statement * @return property wrapper around an expression statement diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values-ko/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values-ko/strings.xml new file mode 100644 index 0000000000..a292e52517 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values-ko/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="mapbox_compassContentDescription">지도 나침반. 지도회전를 북쪽으로 재설정합니다.</string> + <string name="mapbox_attributionsIconContentDescription">속성 정보. 속성 대화를 표시합니다.</string> + <string name="mapbox_myLocationViewContentDescription">로케이션 뷰. 지도에서 현재 위치를 보여줍니다.</string> + <string name="mapbox_mapActionDescription">맵박스로 생성된 지도 표시. 두 손가락으로 드래그하여 화면을 위 아래로 움직이세요. 두 손가락을 이용해 화면을 확대 축소 하세요.</string> + <string name="mapbox_attributionsDialogTitle">안드로이드를 위한 맵박스 맵 SDK</string> + <string name="mapbox_attributionTelemetryTitle">더 나은 맵박스 지도 만들기</string> + <string name="mapbox_attributionTelemetryMessage">당신은 익명의 사용 데이터를 제공함으로써, 오픈스트리트맵과 맵박스 향상에 기여하고 있습니다.</string> + <string name="mapbox_attributionTelemetryPositive">동의</string> + <string name="mapbox_attributionTelemetryNegative">비동의</string> + <string name="mapbox_attributionTelemetryNeutral">추가정보</string> + <string name="mapbox_attributionErrorNoBrowser">웹 브라우저가 설치 되어 있지 않아, 웹 페이지를 열 수 없습니다.</string> + <string name="mapbox_offline_error_region_definition_invalid">제공된 오프라인지역정의가 월드바운즈에 적합하지 않습니다: %s</string> + <string name="mapbox_telemetrySettings">원격 측정 설정</string> + </resources> diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java index e072f07fb9..789a1b2b37 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java @@ -357,6 +357,58 @@ public class LatLngBoundsTest { } @Test + public void intersectNorthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("latitude must be between -90 and 90"); + LatLngBounds intersectLatLngBounds = + LatLngBounds.from(10, 10, 0, 0) + .intersect(200, 200, 0, 0); + } + + @Test + public void intersectSouthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("latitude must be between -90 and 90"); + LatLngBounds intersectLatLngBounds = + LatLngBounds.from(0, 0, -10, -10) + .intersect(0, 0, -200, -200); + } + + @Test + public void intersectSouthLessThanNorthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("LatSouth cannot be less than latNorth"); + + LatLngBounds intersectLatLngBounds = + LatLngBounds.from(10, 10, 0, 0) + .intersect(0, 200, 20, 0); + } + + + @Test + public void intersectEastWrapCheck() { + + LatLngBounds latLngBounds1 = LatLngBounds.from(10, -150, 0, 0); + LatLngBounds latLngBounds2 = LatLngBounds.from(90, 200, 0, 0); + + LatLngBounds intersectLatLngBounds = LatLngBounds.from(10, -160, 0, 0); + + assertEquals(latLngBounds1.intersect(latLngBounds2), intersectLatLngBounds); + assertEquals(latLngBounds2.intersect(latLngBounds1), intersectLatLngBounds); + } + + @Test + public void intersectWestWrapCheck() { + LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, 150); + LatLngBounds latLngBounds2 = LatLngBounds.from(0, 0, -90, -200); + + LatLngBounds intersectLatLngBounds = LatLngBounds.from(0, 0, -10, 160); + + assertEquals(latLngBounds1.intersect(latLngBounds2), intersectLatLngBounds); + assertEquals(latLngBounds2.intersect(latLngBounds1), intersectLatLngBounds); + } + + @Test public void innerUnion() { LatLngBounds latLngBounds = new LatLngBounds.Builder() .include(new LatLng(1, 1)) @@ -391,14 +443,176 @@ public class LatLngBoundsTest { .include(new LatLng(-10, -160)) .build(); - assertEquals("outer union should match", - latLngBounds1.union(latLngBounds2), + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, -160)) + .build()); + + assertEquals(union1, union2); + } + + @Test + public void unionOverDateLine2() { + LatLngBounds latLngBounds1 = new LatLngBounds.Builder() + .include(new LatLng(10, 170)) + .include(new LatLng(0, 160)) + .build(); + + LatLngBounds latLngBounds2 = new LatLngBounds.Builder() + .include(new LatLng(0, 165)) + .include(new LatLng(-10, -160)) + .build(); + + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, new LatLngBounds.Builder() .include(new LatLng(10, 160)) .include(new LatLng(-10, -160)) .build()); + + assertEquals(union1, union2); } + @Test + public void unionOverDateLine3() { + LatLngBounds latLngBounds1 = new LatLngBounds.Builder() + .include(new LatLng(10, -165)) + .include(new LatLng(0, 160)) + .build(); + + LatLngBounds latLngBounds2 = new LatLngBounds.Builder() + .include(new LatLng(0, -170)) + .include(new LatLng(-10, -160)) + .build(); + + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, -160)) + .build()); + + assertEquals(union1, union2); + } + + @Test + public void unionOverDateLine4() { + LatLngBounds latLngBounds1 = new LatLngBounds.Builder() + .include(new LatLng(10, -160)) + .include(new LatLng(0, 160)) + .build(); + + LatLngBounds latLngBounds2 = new LatLngBounds.Builder() + .include(new LatLng(0, -170)) + .include(new LatLng(-10, -175)) + .build(); + + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, -160)) + .build()); + + assertEquals(union1, union2); + } + + @Test + public void unionOverDateLine5() { + LatLngBounds latLngBounds1 = new LatLngBounds.Builder() + .include(new LatLng(10, -160)) + .include(new LatLng(0, 160)) + .build(); + + LatLngBounds latLngBounds2 = new LatLngBounds.Builder() + .include(new LatLng(0, 170)) + .include(new LatLng(-10, 175)) + .build(); + + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, -160)) + .build()); + + assertEquals(union1, union2); + } + + @Test + public void unionOverDateLineReturnWorldLonSpan() { + LatLngBounds latLngBounds1 = LatLngBounds.from(10, -160, -10, -10); + LatLngBounds latLngBounds2 = LatLngBounds.from(10, 10, -10, 160); + + LatLngBounds union1 = latLngBounds1.union(latLngBounds2); + LatLngBounds union2 = latLngBounds2.union(latLngBounds1); + + assertEquals(union1, union2); + assertEquals(union1, LatLngBounds.from(10, 180, -10, -180)); + } + + @Test + public void unionNorthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("latitude must be between -90 and 90"); + LatLngBounds unionLatLngBounds = + LatLngBounds.from(10, 10, 0, 0) + .union(200, 200, 0, 0); + } + + @Test + public void unionSouthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("latitude must be between -90 and 90"); + LatLngBounds unionLatLngBounds = + LatLngBounds.from(0, 0, -10, -10) + .union(0, 0, -200, -200); + } + + @Test + public void unionSouthLessThanNorthCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("LatSouth cannot be less than latNorth"); + + LatLngBounds unionLatLngBounds = + LatLngBounds.from(10, 10, 0, 0) + .union(0, 200, 20, 0); + } + + + @Test + public void unionEastWrapCheck() { + + LatLngBounds latLngBounds1 = LatLngBounds.from(10, 10, 0, 0); + LatLngBounds latLngBounds2 = LatLngBounds.from(90, 200, 0, 0); + LatLngBounds unionLatLngBounds = LatLngBounds.from(90, -160, 0, 0); + + assertEquals(latLngBounds1.union(latLngBounds2), unionLatLngBounds); + assertEquals(latLngBounds2.union(latLngBounds1), unionLatLngBounds); + } + + @Test + public void unionWestWrapCheck() { + LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, -10); + LatLngBounds latLngBounds2 = LatLngBounds.from(0, 0, -90, -200); + + LatLngBounds unionLatLngBounds = LatLngBounds.from(0, 0, -90, 160); + + assertEquals(latLngBounds1.union(latLngBounds2), unionLatLngBounds); + assertEquals(latLngBounds2.union(latLngBounds1), unionLatLngBounds); + } @Test public void northWest() { @@ -524,7 +738,6 @@ public class LatLngBoundsTest { LatLngBounds.from(0, Double.POSITIVE_INFINITY, -20, -20); } - @Test public void testConstructorChecksSouthLatitudeNaN() { exception.expect(IllegalArgumentException.class); @@ -543,7 +756,7 @@ public class LatLngBoundsTest { public void testConstructorChecksSouthLatitudeGreaterThan90() { exception.expect(IllegalArgumentException.class); exception.expectMessage("latitude must be between -90 and 90"); - LatLngBounds.from(20, 20,95, 0); + LatLngBounds.from(20, 20, 95, 0); } @Test diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle index 30e989c79b..80be26d3ae 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle @@ -41,6 +41,7 @@ android { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug } } @@ -72,6 +73,7 @@ dependencies { androidTestImplementation dependenciesList.testRules androidTestImplementation dependenciesList.testEspressoCore androidTestImplementation dependenciesList.testEspressoIntents + androidTestImplementation dependenciesList.testEspressoContrib } apply from: "${rootDir}/gradle/gradle-make.gradle" diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java index 7a1fcbf5f3..89397c30eb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java @@ -16,17 +16,17 @@ public class OrientationTest extends BaseActivityTest { @Test public void testChangeDeviceOrientation() { onView(isRoot()).perform(orientationLandscape()); - waitLoop(2200); + waitAction(2200); onView(isRoot()).perform(orientationPortrait()); - waitLoop(2500); + waitAction(2500); onView(isRoot()).perform(orientationLandscapeReverse()); - waitLoop(500); + waitAction(500); onView(isRoot()).perform(orientationPortraitReverse()); - waitLoop(1250); + waitAction(1250); onView(isRoot()).perform(orientationLandscape()); - waitLoop(750); + waitAction(750); onView(isRoot()).perform(orientationPortrait()); - waitLoop(950); + waitAction(950); onView(isRoot()).perform(orientationLandscapeReverse()); onView(isRoot()).perform(orientationPortraitReverse()); onView(isRoot()).perform(orientationLandscape()); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java new file mode 100644 index 0000000000..26a3a2e4ab --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java @@ -0,0 +1,39 @@ +package com.mapbox.mapboxsdk.testapp.action; + +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.view.View; + +import org.hamcrest.Matcher; + +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; + +public final class WaitAction implements ViewAction { + + private static final long DEFAULT_LOOP_TIME = 375; + private final long loopTime; + + public WaitAction() { + this(DEFAULT_LOOP_TIME); + } + + public WaitAction(long loopTime) { + this.loopTime = loopTime; + } + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + uiController.loopMainThreadForAtLeast(loopTime); + } +} + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java index 3f32443021..6d90c20a46 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java @@ -6,18 +6,19 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.test.espresso.Espresso; import android.support.test.espresso.IdlingResourceTimeoutException; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; import android.support.test.rule.ActivityTestRule; -import android.view.View; + import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.WaitAction; import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; + import junit.framework.Assert; -import org.hamcrest.Matcher; + import org.junit.After; import org.junit.Before; import org.junit.Rule; + import timber.log.Timber; import static android.support.test.espresso.Espresso.onView; @@ -67,12 +68,12 @@ public abstract class BaseActivityTest { onView(withId(id)).check(matches(isDisplayed())); } - protected void waitLoop() { - waitLoop(500); + protected void waitAction() { + waitAction(500); } - protected void waitLoop(long waitTime) { - onView(withId(R.id.mapView)).perform(new LoopAction(waitTime)); + protected void waitAction(long waitTime) { + onView(withId(R.id.mapView)).perform(new WaitAction(waitTime)); } static boolean isConnected(Context context) { @@ -87,29 +88,5 @@ public abstract class BaseActivityTest { Timber.e("@After test: unregister idle resource"); Espresso.unregisterIdlingResources(idlingResource); } - - private class LoopAction implements ViewAction { - - private long loopTime; - - public LoopAction(long loopTime) { - this.loopTime = loopTime; - } - - @Override - public Matcher<View> getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - uiController.loopMainThreadForAtLeast(loopTime); - } - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java index 2a510b4dc5..26aee2de98 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java @@ -62,7 +62,7 @@ public class CompassViewTest extends BaseActivityTest { .build() ))); onView(withId(R.id.compassView)).perform(click()); - waitLoop(); + waitAction(); onView(withId(R.id.compassView)).check(matches(not(isDisplayed()))); invoke(mapboxMap, (uiController, mapboxMap) -> { CameraPosition cameraPosition = mapboxMap.getCameraPosition(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java new file mode 100644 index 0000000000..554bc988a6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java @@ -0,0 +1,129 @@ +package com.mapbox.mapboxsdk.testapp.storage; + +import android.os.Looper; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.mapbox.mapboxsdk.storage.FileSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.WaitAction; +import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity; + +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.Espresso.pressBack; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationLandscape; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class FileSourceTest { + + @Rule + public ActivityTestRule<FeatureOverviewActivity> rule = new ActivityTestRule<>(FeatureOverviewActivity.class); + + private FileSource fileSource; + + @Before + public void setUp() throws Exception { + onView(withId(R.id.recyclerView)).perform(new FileSourceCreator()); + } + + @Test + public void testDefault() throws Exception { + assertFalse("FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testActivateDeactivate() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withId(R.id.recyclerView)).perform(new FileSourceActivator(true)); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.recyclerView)).perform(new FileSourceActivator(false)); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testOpenCloseMapView() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withText("Simple Map")).perform(click()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + pressBack(); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testRotateMapView() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withText("Simple Map")).perform(click()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + onView(isRoot()).perform(orientationLandscape()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + pressBack(); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + private class FileSourceCreator implements ViewAction { + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "Creates the filesource instance on the UI thread"; + } + + @Override + public void perform(UiController uiController, View view) { + assertTrue(Looper.myLooper() == Looper.getMainLooper()); + fileSource = FileSource.getInstance(rule.getActivity()); + } + } + + private class FileSourceActivator implements ViewAction { + + private boolean activate; + + FileSourceActivator(boolean activate) { + this.activate = activate; + } + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "Creates the filesource instance on the UI thread"; + } + + @Override + public void perform(UiController uiController, View view) { + assertTrue(Looper.myLooper() == Looper.getMainLooper()); + if (activate) { + fileSource.activate(); + } else { + fileSource.deactivate(); + } + } + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java index 2d16291832..2a8ac36507 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java @@ -160,4 +160,4 @@ public class BackgroundLayerTest extends BaseActivityTest { assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java index a851fde6dd..101d22a531 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -518,4 +518,4 @@ public class CircleLayerTest extends BaseActivityTest { }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java index f22956072d..84b3e7bd68 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java @@ -354,4 +354,4 @@ public class FillExtrusionLayerTest extends BaseActivityTest { }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java index bdbd8958d2..3e1cbf666d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java @@ -353,4 +353,4 @@ public class FillLayerTest extends BaseActivityTest { assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon"); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java index 549f309e4f..3a81786df4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java @@ -237,4 +237,4 @@ public class HeatmapLayerTest extends BaseActivityTest { assertEquals((Float) layer.getHeatmapOpacity().getValue(), (Float) 0.3f); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java index 1fdc6d6dab..e0121a704a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java @@ -252,4 +252,4 @@ public class HillshadeLayerTest extends BaseActivityTest { assertEquals(layer.getHillshadeAccentColorAsInt(), Color.RED); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java index 40cf0f2927..e35f0edcc4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -545,4 +545,4 @@ public class LineLayerTest extends BaseActivityTest { assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon"); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java index 0410d09369..6e5afdb479 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java @@ -254,4 +254,4 @@ public class RasterLayerTest extends BaseActivityTest { assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java index fc526176d4..23a75d1642 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java @@ -280,6 +280,20 @@ public class RuntimeStyleTests extends BaseActivityTest { }); } + @Test + public void testRemoveNonExistingSource() { + invoke(mapboxMap, (uiController, mapboxMap) -> mapboxMap.removeSource("source")); + } + + @Test + public void testRemoveNonExistingLayer() { + invoke(mapboxMap, (uiController, mapboxMap) -> { + mapboxMap.removeLayer("layer"); + mapboxMap.removeLayerAt(mapboxMap.getLayers().size() + 1); + mapboxMap.removeLayerAt(-1); + }); + } + /** * https://github.com/mapbox/mapbox-gl-native/issues/7973 */ diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java index 62f73b1507..fe38fef253 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -1392,4 +1392,4 @@ public class SymbolLayerTest extends BaseActivityTest { assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP); }); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs index 935813899f..575f64e809 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs @@ -150,7 +150,7 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { assertEquals((<%- propertyType(property) %>) layer.get<%- camelize(property.name) %>().getValue(), (<%- propertyType(property) %>) <%- defaultValueJava(property) %>); }); } -<% if (isDataDriven(property)) { -%> +<% if (property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven') { -%> <% if (!(property.name.endsWith("-font")||property.name.endsWith("-offset"))) { -%> @Test @@ -188,4 +188,4 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { <% } -%> <% } -%> <% } -%> -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index 442635f909..fb1d0ef8a2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -69,9 +69,9 @@ android:value=".activity.FeatureOverviewActivity" /> </activity> <activity - android:name=".activity.annotation.AnimatedMarkerActivity" - android:description="@string/description_animated_marker" - android:label="@string/activity_animated_marker"> + android:name=".activity.annotation.AnimatedSymbolLayerActivity" + android:description="@string/description_animated_symbollayer" + android:label="@string/activity_animated_symbollayer"> <meta-data android:name="@string/category" android:value="@string/category_annotation" /> @@ -794,4 +794,4 @@ <!-- android:value="true" /> --> </application> -</manifest>
\ No newline at end of file +</manifest> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java deleted file mode 100644 index e6db071141..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java +++ /dev/null @@ -1,283 +0,0 @@ -package com.mapbox.mapboxsdk.testapp.activity.annotation; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.animation.TypeEvaluator; -import android.animation.ValueAnimator; -import android.os.Bundle; -import android.support.annotation.DrawableRes; -import android.support.v4.content.res.ResourcesCompat; -import android.support.v7.app.AppCompatActivity; -import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator; - -import com.mapbox.geojson.Point; -import com.mapbox.mapboxsdk.annotations.Icon; -import com.mapbox.mapboxsdk.annotations.IconFactory; -import com.mapbox.mapboxsdk.annotations.Marker; -import com.mapbox.mapboxsdk.annotations.MarkerView; -import com.mapbox.mapboxsdk.annotations.MarkerViewManager; -import com.mapbox.mapboxsdk.annotations.MarkerViewOptions; -import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapbox.mapboxsdk.maps.MapView; -import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.utils.IconUtils; -import com.mapbox.turf.TurfMeasurement; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Test activity showcasing animating MarkerViews. - */ -public class AnimatedMarkerActivity extends AppCompatActivity { - - private MapView mapView; - private MapboxMap mapboxMap; - - private LatLng dupontCircle = new LatLng(38.90962, -77.04341); - - private Marker passengerMarker = null; - private MarkerView carMarker = null; - - private Runnable animationRunnable; - - private List<MarkerView> markerViews = new ArrayList<>(); - private boolean stopped; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_animated_marker); - - mapView = (MapView) findViewById(R.id.mapView); - mapView.onCreate(savedInstanceState); - mapView.getMapAsync(mapboxMap -> { - AnimatedMarkerActivity.this.mapboxMap = mapboxMap; - setupMap(); - - animationRunnable = () -> { - for (int i = 0; i < 10; i++) { - addRandomCar(); - } - addPassenger(); - addMainCar(); - }; - mapView.post(animationRunnable); - }); - } - - private void setupMap() { - CameraPosition cameraPosition = new CameraPosition.Builder() - .target(dupontCircle) - .zoom(15) - .build(); - mapboxMap.setCameraPosition(cameraPosition); - } - - private void addPassenger() { - if (isActivityStopped()) { - return; - } - - LatLng randomLatLng = getLatLngInBounds(); - - if (passengerMarker == null) { - Icon icon = IconUtils.drawableToIcon(this, R.drawable.ic_directions_run_black, - ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme())); - passengerMarker = mapboxMap.addMarker(new MarkerViewOptions() - .position(randomLatLng) - .icon(icon)); - } else { - passengerMarker.setPosition(randomLatLng); - } - } - - private void addMainCar() { - if (isActivityStopped()) { - return; - } - - LatLng randomLatLng = getLatLngInBounds(); - - if (carMarker == null) { - carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top, - markerView -> { - // Make sure the car marker is selected so that it's always brought to the front (#5285) - mapboxMap.selectMarker(carMarker); - animateMoveToPassenger(carMarker); - }); - markerViews.add(carMarker); - } else { - carMarker.setPosition(randomLatLng); - } - } - - private void animateMoveToPassenger(final MarkerView car) { - if (isActivityStopped()) { - return; - } - - ValueAnimator animator = animateMoveMarker(car, passengerMarker.getPosition()); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - addPassenger(); - animateMoveToPassenger(car); - } - }); - } - - protected void addRandomCar() { - markerViews.add(createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top, - markerView -> randomlyMoveMarker(markerView))); - } - - private void randomlyMoveMarker(final MarkerView marker) { - if (isActivityStopped()) { - return; - } - - ValueAnimator animator = animateMoveMarker(marker, getLatLngInBounds()); - - // Add listener to restart animation on end - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - randomlyMoveMarker(marker); - } - }); - } - - private ValueAnimator animateMoveMarker(final MarkerView marker, LatLng to) { - marker.setRotation((float) getBearing(marker.getPosition(), to)); - - final ValueAnimator markerAnimator = ObjectAnimator.ofObject( - marker, "position", new LatLngEvaluator(), marker.getPosition(), to); - markerAnimator.setDuration((long) (10 * marker.getPosition().distanceTo(to))); - markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); - - // Start - markerAnimator.start(); - - return markerAnimator; - } - - private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource, - MarkerViewManager.OnMarkerViewAddedListener listener) { - Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this) - .fromResource(carResource); - - // View Markers - return mapboxMap.addMarker(new MarkerViewOptions() - .position(start) - .icon(icon), listener); - - // GL Markers -// return mapboxMap.addMarker(new MarkerOptions() -// .position(start) -// .icon(icon)); - - } - - private LatLng getLatLngInBounds() { - LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds; - Random generator = new Random(); - double randomLat = bounds.getLatSouth() + generator.nextDouble() - * (bounds.getLatNorth() - bounds.getLatSouth()); - double randomLon = bounds.getLonWest() + generator.nextDouble() - * (bounds.getLonEast() - bounds.getLonWest()); - return new LatLng(randomLat, randomLon); - } - - @Override - protected void onStart() { - super.onStart(); - mapView.onStart(); - } - - @Override - protected void onResume() { - super.onResume(); - mapView.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - mapView.onPause(); - } - - @Override - protected void onStop() { - super.onStop(); - - stopped = true; - - // Stop ongoing animations, prevent memory leaks - if (mapboxMap != null) { - MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager(); - for (MarkerView markerView : markerViews) { - View view = markerViewManager.getView(markerView); - if (view != null) { - view.animate().cancel(); - } - } - } - - // onStop - mapView.onStop(); - mapView.removeCallbacks(animationRunnable); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - mapView.onSaveInstanceState(outState); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mapView.onDestroy(); - } - - @Override - public void onLowMemory() { - super.onLowMemory(); - mapView.onLowMemory(); - } - - /** - * Evaluator for LatLng pairs - */ - private static class LatLngEvaluator implements TypeEvaluator<LatLng> { - - private LatLng latLng = new LatLng(); - - @Override - public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { - latLng.setLatitude(startValue.getLatitude() - + ((endValue.getLatitude() - startValue.getLatitude()) * fraction)); - latLng.setLongitude(startValue.getLongitude() - + ((endValue.getLongitude() - startValue.getLongitude()) * fraction)); - return latLng; - } - } - - private double getBearing(LatLng from, LatLng to) { - return TurfMeasurement.bearing( - Point.fromLngLat(from.getLongitude(), from.getLatitude()), - Point.fromLngLat(to.getLongitude(), to.getLatitude()) - ); - } - - private boolean isActivityStopped() { - return stopped; - } -} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java index 6277dffe91..5983fb367a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java @@ -172,9 +172,12 @@ public class CameraAnimatorActivity extends AppCompatActivity implements OnMapRe if (mapboxMap == null) { return false; } - findViewById(R.id.fab).setVisibility(View.GONE); - resetCameraPosition(); - playAnimation(item.getItemId()); + + if (item.getItemId() != android.R.id.home) { + findViewById(R.id.fab).setVisibility(View.GONE); + resetCameraPosition(); + playAnimation(item.getItemId()); + } return super.onOptionsItemSelected(item); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java index 930626078d..f5e0371aad 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java @@ -1,14 +1,13 @@ package com.mapbox.mapboxsdk.testapp.activity.fragment; -import android.app.FragmentTransaction; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; - import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapFragment; +import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -20,53 +19,71 @@ import com.mapbox.mapboxsdk.testapp.R; * Uses MapboxMapOptions to initialise the Fragment. * </p> */ -public class MapFragmentActivity extends AppCompatActivity implements OnMapReadyCallback { +public class MapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback, + OnMapReadyCallback, MapView.OnMapChangedListener { private MapboxMap mapboxMap; + private MapView mapView; + private boolean initialCameraAnimation = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_fragment); - - MapFragment mapFragment; if (savedInstanceState == null) { - final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + MapFragment mapFragment = MapFragment.newInstance(createFragmentOptions()); + getFragmentManager() + .beginTransaction() + .add(R.id.fragment_container,mapFragment, "com.mapbox.map") + .commit(); + mapFragment.getMapAsync(this); + } + } - MapboxMapOptions options = new MapboxMapOptions(); - options.styleUrl(Style.OUTDOORS); + private MapboxMapOptions createFragmentOptions() { + MapboxMapOptions options = new MapboxMapOptions(); + options.styleUrl(Style.OUTDOORS); - options.scrollGesturesEnabled(false); - options.zoomGesturesEnabled(false); - options.tiltGesturesEnabled(false); - options.rotateGesturesEnabled(false); + options.scrollGesturesEnabled(false); + options.zoomGesturesEnabled(false); + options.tiltGesturesEnabled(false); + options.rotateGesturesEnabled(false); + options.debugActive(false); - options.debugActive(false); + LatLng dc = new LatLng(38.90252, -77.02291); - LatLng dc = new LatLng(38.90252, -77.02291); + options.minZoomPreference(9); + options.maxZoomPreference(11); + options.camera(new CameraPosition.Builder() + .target(dc) + .zoom(11) + .build()); + return options; + } - options.minZoomPreference(9); - options.maxZoomPreference(11); - options.camera(new CameraPosition.Builder() - .target(dc) - .zoom(11) - .build()); + @Override + public void onMapViewReady(MapView map) { + mapView = map; + mapView.addOnMapChangedListener(this); + } - mapFragment = MapFragment.newInstance(options); + @Override + public void onMapReady(MapboxMap map) { + mapboxMap = map; + } - transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map"); - transaction.commit(); - } else { - mapFragment = (MapFragment) getFragmentManager().findFragmentByTag("com.mapbox.map"); + @Override + public void onMapChanged(int change) { + if (initialCameraAnimation && change == MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED) { + mapboxMap.animateCamera( + CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 5000); + initialCameraAnimation = false; } - - mapFragment.getMapAsync(this); } @Override - public void onMapReady(MapboxMap map) { - mapboxMap = map; - mapboxMap.animateCamera( - CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000); + protected void onDestroy() { + super.onDestroy(); + mapView.removeOnMapChangedListener(this); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java index 4f828060ee..f494a9231e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java @@ -1,13 +1,13 @@ package com.mapbox.mapboxsdk.testapp.activity.fragment; import android.os.Bundle; -import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; - import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapFragment; +import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -20,51 +20,71 @@ import com.mapbox.mapboxsdk.testapp.R; * Uses MapboxMapOptions to initialise the Fragment. * </p> */ -public class SupportMapFragmentActivity extends AppCompatActivity implements OnMapReadyCallback { +public class SupportMapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback, + OnMapReadyCallback, MapView.OnMapChangedListener { private MapboxMap mapboxMap; + private MapView mapView; + private boolean initialCameraAnimation = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_fragment); - - SupportMapFragment mapFragment; if (savedInstanceState == null) { - final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); - - MapboxMapOptions options = new MapboxMapOptions(); - options.styleUrl(Style.SATELLITE_STREETS); - - options.debugActive(false); - options.compassEnabled(false); - options.attributionEnabled(false); - options.logoEnabled(false); + SupportMapFragment mapFragment = SupportMapFragment.newInstance(createFragmentOptions()); + getSupportFragmentManager() + .beginTransaction() + .add(R.id.fragment_container, mapFragment, "com.mapbox.map") + .commit(); + mapFragment.getMapAsync(this); + } + } - LatLng dc = new LatLng(38.90252, -77.02291); + private MapboxMapOptions createFragmentOptions() { + MapboxMapOptions options = new MapboxMapOptions(); + options.styleUrl(Style.MAPBOX_STREETS); - options.minZoomPreference(9); - options.maxZoomPreference(11); - options.camera(new CameraPosition.Builder() - .target(dc) - .zoom(11) - .build()); + options.scrollGesturesEnabled(false); + options.zoomGesturesEnabled(false); + options.tiltGesturesEnabled(false); + options.rotateGesturesEnabled(false); + options.debugActive(false); - mapFragment = SupportMapFragment.newInstance(options); + LatLng dc = new LatLng(38.90252, -77.02291); - transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map"); - transaction.commit(); - } else { - mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag("com.mapbox.map"); - } + options.minZoomPreference(9); + options.maxZoomPreference(11); + options.camera(new CameraPosition.Builder() + .target(dc) + .zoom(11) + .build()); + return options; + } - mapFragment.getMapAsync(this); + @Override + public void onMapViewReady(MapView map) { + mapView = map; + mapView.addOnMapChangedListener(this); } @Override public void onMapReady(MapboxMap map) { mapboxMap = map; - mapboxMap.animateCamera( - CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000); } -} + + @Override + public void onMapChanged(int change) { + if (initialCameraAnimation && change == MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED) { + mapboxMap.animateCamera( + CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 5000); + initialCameraAnimation = false; + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.removeOnMapChangedListener(this); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java index c5ad467673..e1a524790d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java @@ -14,7 +14,7 @@ import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; - +import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.offline.OfflineRegion; import com.mapbox.mapboxsdk.testapp.R; @@ -27,10 +27,13 @@ import java.util.List; /** * Test activity showing integration of updating metadata of an OfflineRegion. */ -public class UpdateMetadataActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class UpdateMetadataActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, + AdapterView.OnItemLongClickListener { private OfflineRegionMetadataAdapter adapter; + private MapView mapView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -40,6 +43,7 @@ public class UpdateMetadataActivity extends AppCompatActivity implements Adapter listView.setAdapter(adapter = new OfflineRegionMetadataAdapter(this)); listView.setEmptyView(findViewById(android.R.id.empty)); listView.setOnItemClickListener(this); + listView.setOnItemLongClickListener(this); } @Override @@ -64,6 +68,18 @@ public class UpdateMetadataActivity extends AppCompatActivity implements Adapter builder.show(); } + @Override + public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { + ViewGroup container = (ViewGroup) findViewById(R.id.container); + container.removeAllViews(); + container.addView(mapView = new MapView(view.getContext())); + mapView.setOfflineRegionDefinition(adapter.getItem(position).getDefinition()); + mapView.onCreate(null); + mapView.onStart(); + mapView.onResume(); + return true; + } + private void updateMetadata(OfflineRegion region, byte[] metadata) { region.updateMetadata(metadata, new OfflineRegion.OfflineRegionUpdateMetadataCallback() { @Override @@ -104,6 +120,16 @@ public class UpdateMetadataActivity extends AppCompatActivity implements Adapter }); } + @Override + protected void onDestroy() { + super.onDestroy(); + if (mapView != null) { + mapView.onPause(); + mapView.onStop(); + mapView.onDestroy(); + } + } + private static class OfflineRegionMetadataAdapter extends BaseAdapter { private Context context; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/ZoomFunctionSymbolLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/ZoomFunctionSymbolLayerActivity.java index df06c9c42d..81fd2c6ff8 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/ZoomFunctionSymbolLayerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/ZoomFunctionSymbolLayerActivity.java @@ -5,7 +5,6 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; - import com.google.gson.JsonObject; import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; @@ -16,16 +15,13 @@ import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import com.mapbox.mapboxsdk.testapp.R; - +import timber.log.Timber; import java.util.List; -import timber.log.Timber; - import static com.mapbox.mapboxsdk.style.expressions.Expression.get; -import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; -import static com.mapbox.mapboxsdk.style.expressions.Expression.linear; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.step; import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; @@ -44,7 +40,6 @@ public class ZoomFunctionSymbolLayerActivity extends AppCompatActivity { private static final String BUS_MAKI_ICON_ID = "bus-11"; private static final String CAFE_MAKI_ICON_ID = "cafe-11"; private static final String KEY_PROPERTY_SELECTED = "selected"; - private static final float ZOOM_STOP_MIN_VALUE = 7.0f; private static final float ZOOM_STOP_MAX_VALUE = 12.0f; private MapView mapView; @@ -103,11 +98,9 @@ public class ZoomFunctionSymbolLayerActivity extends AppCompatActivity { layer = new SymbolLayer(LAYER_ID, SOURCE_ID); layer.setProperties( iconImage( - interpolate( - linear(), zoom(), - stop(ZOOM_STOP_MIN_VALUE, BUS_MAKI_ICON_ID), - stop(ZOOM_STOP_MAX_VALUE, CAFE_MAKI_ICON_ID) - ) + step(zoom(), literal(BUS_MAKI_ICON_ID), + stop(ZOOM_STOP_MAX_VALUE, CAFE_MAKI_ICON_ID) + ) ), iconSize( switchCase( diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml index 0566757d58..252af714e7 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml @@ -10,9 +10,9 @@ android:id="@id/mapView" android:layout_width="match_parent" android:layout_height="wrap_content" - app:mapbox_cameraTargetLat="51.502615" - app:mapbox_cameraTargetLng="4.972326" - app:mapbox_cameraZoom="6" + app:mapbox_cameraTargetLat="38.90962" + app:mapbox_cameraTargetLng="-77.04341" + app:mapbox_cameraZoom="15" app:mapbox_styleUrl="@string/mapbox_style_light"/> </LinearLayout> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_metadata_update.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_metadata_update.xml index 1eb999caf5..501bc55743 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_metadata_update.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_metadata_update.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout + android:id="@+id/container" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml index 5238176ce8..17d6ad57c6 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml @@ -19,7 +19,7 @@ <string name="description_offline">Offline Map example</string> <string name="description_update_metadata">Update metadata example</string> <string name="description_offline_region_delete">Delete region example</string> - <string name="description_animated_marker">Animate the position change of a marker</string> + <string name="description_animated_symbollayer">Animate the position change of a symbol layer</string> <string name="description_polyline">Add a polyline to a map</string> <string name="description_polygon">Add a polygon to a map</string> <string name="description_scroll_by">Scroll with pixels in x,y direction</string> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml index 89ec586950..3f011bd3ed 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml @@ -4,7 +4,7 @@ <string name="activity_map_fragment">Map Fragment</string> <string name="activity_multimap">Multiple Maps on Screen</string> <string name="activity_add_bulk_markers">Add Markers In Bulk</string> - <string name="activity_animated_marker">Animated Markers</string> + <string name="activity_animated_symbollayer">Animated SymbolLayer</string> <string name="activity_dynamic_marker">Dynamic Marker</string> <string name="activity_polyline">Polyline</string> <string name="activity_polygon">Polygon</string> diff --git a/platform/android/README.md b/platform/android/README.md index 1dbdeee343..31e0a94f2c 100644 --- a/platform/android/README.md +++ b/platform/android/README.md @@ -12,7 +12,7 @@ Alright. So, actually, you may be in the wrong place. From here on in, this READ **To install and use the Mapbox Maps SDK for Android in an application, see the [Mapbox Maps SDK for Android website](https://www.mapbox.com/install/android/).** -[![](https://www.mapbox.com/android-sdk/images/splash.png)](https://www.mapbox.com/android-sdk/) +[![](https://www.mapbox.com/android-docs/assets/overview-map-sdk-322-9abe118316efb5910b6101e222a2e57c.png)](https://www.mapbox.com/android-sdk/) ### Setup environment @@ -89,15 +89,14 @@ More information about building and distributing this project in [DISTRIBUTE.md] #### Using the SDK snapshot -Instead of using the latest stable release of the Maps SDK for Android, you can use a "snapshot" or the beta version if there is one available. Our snapshots are built every time a Github pull request adds code to this repository's `master` branch. If you'd like to use a snapshot build, your Android project's gradle file should have -SNAPSHOT appended to the SDK version number. For example `5.2.0-SNAPSHOT` or: +Instead of using the latest stable release of the Maps SDK for Android, you can use a "snapshot" or the beta version if there is one available. Our snapshots are built every time a Github pull request adds code to this repository's `master` branch. If you'd like to use a snapshot build, your Android project's gradle file should have -SNAPSHOT appended to the SDK version number. For example, the `5.2.0-SNAPSHOT` would look like: ```java // Mapbox SDK dependency -compile('com.mapbox.mapboxsdk:mapbox-android-sdk:5.2.0-SNAPSHOT@aar') { - transitive = true -} +implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:5.2.0-SNAPSHOT' ``` -You need to have the section below in your build.gradle root folder to be able to resolve the SNAPSHOT dependencies: + +You also need to have the section below in your build.gradle root folder to be able to resolve the SNAPSHOT dependencies: ``` allprojects { repositories { diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 16238f41c1..45cddd9688 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -5,7 +5,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.2' } } diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 77074dc82c..c25e48de05 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -10,7 +10,7 @@ set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> ruT <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") -if ((ANDROID_ABI STREQUAL "armeabi") OR (ANDROID_ABI STREQUAL "armeabi-v7a") OR (ANDROID_ABI STREQUAL "arm64-v8a") OR +if ((ANDROID_ABI STREQUAL "armeabi-v7a") OR (ANDROID_ABI STREQUAL "arm64-v8a") OR (ANDROID_ABI STREQUAL "x86") OR (ANDROID_ABI STREQUAL "x86_64")) # Use Identical Code Folding on platforms that support the gold linker. set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=gold -Wl,--icf=safe ${CMAKE_EXE_LINKER_FLAGS}") diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle index a5c6ad0da3..ff61b1d074 100644 --- a/platform/android/gradle/dependencies.gradle +++ b/platform/android/gradle/dependencies.gradle @@ -2,24 +2,23 @@ ext { androidVersions = [ minSdkVersion : 14, - targetSdkVersion : 25, - compileSdkVersion: 25, - buildToolsVersion: '26.0.3' + targetSdkVersion : 27, + compileSdkVersion: 27, + buildToolsVersion: '27.0.3' ] versions = [ - mapboxServices : '3.0.1', - mapboxTelemetry: '3.0.2', + mapboxServices : '3.1.0', + mapboxTelemetry: '3.1.1', mapboxGestures : '0.2.0', - supportLib : '25.4.0', - espresso : '3.0.1', - testRunner : '1.0.1', - leakCanary : '1.5.1', - lost : '3.0.4', + supportLib : '27.1.1', + espresso : '3.0.2', + testRunner : '1.0.2', + leakCanary : '1.5.4', junit : '4.12', - mockito : '2.10.0', - robolectric : '3.5.1', - timber : '4.5.1', + mockito : '2.18.3', + robolectric : '3.8', + timber : '4.7.0', okhttp : '3.10.0' ] @@ -40,6 +39,7 @@ ext { testRules : "com.android.support.test:rules:${versions.testRunner}", testEspressoCore : "com.android.support.test.espresso:espresso-core:${versions.espresso}", testEspressoIntents : "com.android.support.test.espresso:espresso-intents:${versions.espresso}", + testEspressoContrib : "com.android.support.test.espresso:espresso-contrib:${versions.espresso}", supportAnnotations : "com.android.support:support-annotations:${versions.supportLib}", supportAppcompatV7 : "com.android.support:appcompat-v7:${versions.supportLib}", @@ -47,11 +47,10 @@ ext { supportDesign : "com.android.support:design:${versions.supportLib}", supportRecyclerView : "com.android.support:recyclerview-v7:${versions.supportLib}", - lost : "com.mapzen.android:lost:${versions.lost}", gmsLocation : 'com.google.android.gms:play-services-location:11.0.4', timber : "com.jakewharton.timber:timber:${versions.timber}", okhttp3 : "com.squareup.okhttp3:okhttp:${versions.okhttp}", leakCanaryDebug : "com.squareup.leakcanary:leakcanary-android:${versions.leakCanary}", leakCanaryRelease : "com.squareup.leakcanary:leakcanary-android-no-op:${versions.leakCanary}" ] -}
\ No newline at end of file +} diff --git a/platform/android/gradle/gradle-dependencies-graph.gradle b/platform/android/gradle/gradle-dependencies-graph.gradle new file mode 100644 index 0000000000..5cbc7b974f --- /dev/null +++ b/platform/android/gradle/gradle-dependencies-graph.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "com.vanniktech:gradle-dependency-graph-generator-plugin:0.3.0" + } +} + +import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorPlugin +import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension.Generator +import com.vanniktech.dependency.graph.generator.dot.GraphFormattingOptions +import com.vanniktech.dependency.graph.generator.dot.Color +import com.vanniktech.dependency.graph.generator.dot.Shape +import com.vanniktech.dependency.graph.generator.dot.Style + +plugins.apply(DependencyGraphGeneratorPlugin) + +def mapboxGenerator = new Generator( + "mapboxLibraries", // Suffix for our Gradle task. + "", // Root suffix that we don't want in this case. + { dependency -> dependency.getModuleGroup().startsWith("com.mapbox.mapboxsdk") }, // Only want Mapbox libs. + { dependency -> true }, // Include transitive dependencies. +) + +dependencyGraphGenerator { + generators = [mapboxGenerator] +} diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index bf1b63c346..84af82d181 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Mon May 14 12:12:39 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/platform/android/scripts/exclude-activity-gen.json b/platform/android/scripts/exclude-activity-gen.json index eff7fb9cbf..157808aa51 100644 --- a/platform/android/scripts/exclude-activity-gen.json +++ b/platform/android/scripts/exclude-activity-gen.json @@ -18,7 +18,7 @@ "LocationPickerActivity", "GeoJsonClusteringActivity", "RuntimeStyleTestActivity", - "AnimatedMarkerActivity", + "AnimatedSymbolLayerActivity", "ViewPagerActivity", "MapFragmentActivity", "SupportMapFragmentActivity", diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index 3b0363cc19..05ca957974 100755 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -267,19 +267,17 @@ global.propertyValueDoc = function (property, value) { return doc; }; -global.isDataDriven = function (property) { - return property['property-function'] === true; -}; - global.isLightProperty = function (property) { return property['light-property'] === true; }; global.propertyValueType = function (property) { - if (isDataDriven(property)) { - return `DataDrivenPropertyValue<${evaluatedType(property)}>`; - } else { - return `PropertyValue<${evaluatedType(property)}>`; + switch (property['property-type']) { + case 'data-driven': + case 'cross-faded-data-driven': + return `DataDrivenPropertyValue<${evaluatedType(property)}>`; + default: + return `PropertyValue<${evaluatedType(property)}>`; } }; @@ -318,11 +316,11 @@ global.evaluatedType = function (property) { }; global.supportsZoomFunction = function (property) { - return property['zoom-function'] === true; + return property.expression && property.expression.parameters.indexOf('zoom') > -1; }; global.supportsPropertyFunction = function (property) { - return property['property-function'] === true; + return property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; }; // Template processing // diff --git a/platform/android/src/bitmap.cpp b/platform/android/src/bitmap.cpp index 46e7253050..0d3670b666 100644 --- a/platform/android/src/bitmap.cpp +++ b/platform/android/src/bitmap.cpp @@ -1,6 +1,7 @@ #include "bitmap.hpp" #include <android/bitmap.h> +#include <mbgl/util/logging.hpp> namespace mbgl { namespace android { @@ -17,7 +18,7 @@ public: ~PixelGuard() { const int result = AndroidBitmap_unlockPixels(&env, jni::Unwrap(*bitmap)); if (result != ANDROID_BITMAP_RESULT_SUCCESS) { - throw std::runtime_error("bitmap decoding: could not unlock pixels"); + Log::Warning(mbgl::Event::General, "Bitmap decoding: could not unlock pixels"); } } diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp index d8d715dbd3..58a91f6cf0 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -83,6 +83,13 @@ void FileSource::pause(jni::JNIEnv&) { } } +jni::jboolean FileSource::isResumed(jni::JNIEnv&) { + if (activationCounter) { + return (jboolean) (activationCounter > 0); + } + return (jboolean) false; +} + jni::Class<FileSource> FileSource::javaClass; FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) { @@ -114,7 +121,8 @@ void FileSource::registerNative(jni::JNIEnv& env) { METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"), METHOD(&FileSource::setResourceTransform, "setResourceTransform"), METHOD(&FileSource::resume, "activate"), - METHOD(&FileSource::pause, "deactivate") + METHOD(&FileSource::pause, "deactivate"), + METHOD(&FileSource::isResumed, "isActivated") ); } diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 194f784622..e4295e1b84 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -45,6 +45,8 @@ public: void pause(jni::JNIEnv&); + jni::jboolean isResumed(jni::JNIEnv&); + static jni::Class<FileSource> javaClass; static FileSource* getNativePeer(jni::JNIEnv&, jni::Object<FileSource>); diff --git a/platform/android/src/geojson/point.cpp b/platform/android/src/geojson/point.cpp index aa9dc1a7f6..8a9656ea14 100644 --- a/platform/android/src/geojson/point.cpp +++ b/platform/android/src/geojson/point.cpp @@ -59,4 +59,4 @@ jni::Class<Point> Point::javaClass; } // namespace geojson } // namespace android -} // namespace mbgl
\ No newline at end of file +} // namespace mbgl diff --git a/platform/android/src/geometry/lat_lng_bounds.cpp b/platform/android/src/geometry/lat_lng_bounds.cpp index ec1a32fed5..827ee52e95 100644 --- a/platform/android/src/geometry/lat_lng_bounds.cpp +++ b/platform/android/src/geometry/lat_lng_bounds.cpp @@ -9,14 +9,17 @@ jni::Object<LatLngBounds> LatLngBounds::New(jni::JNIEnv& env, mbgl::LatLngBounds } mbgl::LatLngBounds LatLngBounds::getLatLngBounds(jni::JNIEnv& env, jni::Object<LatLngBounds> bounds) { - static auto swLat = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "latitudeSouth"); - static auto swLon = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "longitudeWest"); - static auto neLat = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "latitudeNorth"); - static auto neLon = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "longitudeEast"); - return mbgl::LatLngBounds::hull( - { bounds.Get(env, swLat), bounds.Get(env, swLon) }, - { bounds.Get(env, neLat), bounds.Get(env, neLon) } - ); + static auto swLatField = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "latitudeSouth"); + static auto swLonField = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "longitudeWest"); + static auto neLatField = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "latitudeNorth"); + static auto neLonField = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "longitudeEast"); + + mbgl::LatLng sw = { bounds.Get(env, swLatField), bounds.Get(env, swLonField) }; + mbgl::LatLng ne = { bounds.Get(env, neLatField), bounds.Get(env, neLonField) }; + + sw.unwrapForShortestPath(ne); + + return mbgl::LatLngBounds::hull(sw, ne); } void LatLngBounds::registerNative(jni::JNIEnv& env) { diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp index f7e16b7091..ba6fdc63b0 100644 --- a/platform/android/src/map_renderer.cpp +++ b/platform/android/src/map_renderer.cpp @@ -29,6 +29,7 @@ MapRenderer::MapRenderer(jni::JNIEnv& _env, jni::Object<MapRenderer> obj, MapRenderer::~MapRenderer() = default; void MapRenderer::reset() { + destroyed = true; // Make sure to destroy the renderer on the GL Thread auto self = ActorRef<MapRenderer>(*this, mailbox); self.ask(&MapRenderer::resetRenderer).wait(); @@ -88,8 +89,10 @@ void MapRenderer::requestSnapshot(SnapshotCallback callback) { self.invoke( &MapRenderer::scheduleSnapshot, std::make_unique<SnapshotCallback>([&, callback=std::move(callback), runloop=util::RunLoop::Get()](PremultipliedImage image) { - runloop->invoke([callback=std::move(callback), image=std::move(image)]() mutable { - callback(std::move(image)); + runloop->invoke([callback=std::move(callback), image=std::move(image), renderer=std::move(this)]() mutable { + if (renderer && !renderer->destroyed) { + callback(std::move(image)); + } }); snapshotCallback.reset(); }) @@ -136,7 +139,7 @@ void MapRenderer::render(JNIEnv&) { renderer->render(*params); // Deliver the snapshot if requested - if (snapshotCallback && !paused) { + if (snapshotCallback) { snapshotCallback->operator()(backend->readFramebuffer()); snapshotCallback.reset(); } @@ -174,14 +177,6 @@ void MapRenderer::onSurfaceChanged(JNIEnv&, jint width, jint height) { requestRender(); } -void MapRenderer::onResume(JNIEnv&) { - paused = false; -} - -void MapRenderer::onPause(JNIEnv&) { - paused = true; -} - // Static methods // jni::Class<MapRenderer> MapRenderer::javaClass; @@ -200,11 +195,7 @@ void MapRenderer::registerNative(jni::JNIEnv& env) { METHOD(&MapRenderer::onSurfaceCreated, "nativeOnSurfaceCreated"), METHOD(&MapRenderer::onSurfaceChanged, - "nativeOnSurfaceChanged"), - METHOD(&MapRenderer::onResume, - "nativeOnResume"), - METHOD(&MapRenderer::onPause, - "nativeOnPause")); + "nativeOnSurfaceChanged")); } MapRenderer& MapRenderer::getNativePeer(JNIEnv& env, jni::Object<MapRenderer> jObject) { diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp index 5fb5ef1a61..97d2db4a91 100644 --- a/platform/android/src/map_renderer.hpp +++ b/platform/android/src/map_renderer.hpp @@ -98,10 +98,6 @@ private: void onSurfaceChanged(JNIEnv&, jint width, jint height); - void onResume(JNIEnv&); - - void onPause(JNIEnv&); - private: GenericUniqueWeakObject<MapRenderer> javaPeer; @@ -124,7 +120,7 @@ private: std::mutex updateMutex; bool framebufferSizeChanged = false; - std::atomic<bool> paused {false}; + std::atomic<bool> destroyed {false}; std::unique_ptr<SnapshotCallback> snapshotCallback; }; diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index 34366d836a..f655f13ea8 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -5,6 +5,7 @@ #include <mbgl/util/thread.hpp> #include <mbgl/util/timer.hpp> #include <mbgl/actor/scheduler.hpp> +#include <mbgl/util/event.hpp> #include <android/looper.h> @@ -17,6 +18,7 @@ #include <fcntl.h> #include <unistd.h> +#include <mbgl/util/logging.hpp> #define PIPE_OUT 0 #define PIPE_IN 1 @@ -119,11 +121,11 @@ RunLoop::Impl::~Impl() { alarm.reset(); if (ALooper_removeFd(loop, fds[PIPE_OUT]) != 1) { - throw std::runtime_error("Failed to remove file descriptor from Looper."); + Log::Error(mbgl::Event::General, "Failed to remove file descriptor from Looper"); } if (close(fds[PIPE_IN]) || close(fds[PIPE_OUT])) { - throw std::runtime_error("Failed to close file descriptor."); + Log::Error(mbgl::Event::General, "Failed to close file descriptor."); } ALooper_release(loop); diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index 6fe6e3cb29..c7a6bcd3a3 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -157,14 +157,12 @@ namespace android { using namespace mbgl::style::conversion; Filter filter = layer.accept(GetFilterEvaluator()); - - jni::Object<gson::JsonElement> converted; - if (filter.is<ExpressionFilter>()) { - ExpressionFilter filterExpression = filter.get<ExpressionFilter>(); - mbgl::Value expressionValue = filterExpression.expression.get()->serialize(); - converted = gson::JsonElement::New(env, expressionValue); + if (filter.expression) { + mbgl::Value expressionValue = (*filter.expression)->serialize(); + return gson::JsonElement::New(env, expressionValue); + } else { + return jni::Object<gson::JsonElement>(); } - return converted; } struct SetSourceLayerEvaluator { |