Merge branch 'release-boba' into master

# Conflicts:
#	circle.yml
#	include/mbgl/style/expression/let.hpp
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
#	platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
#	platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
#	platform/android/gradle/dependencies.gradle
#	platform/android/src/example_custom_layer.cpp
#	platform/android/src/geojson/point.cpp
#	platform/darwin/src/NSPredicate+MGLAdditions.mm
#	platform/darwin/test/MGLExpressionTests.mm
#	platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec
#	platform/ios/Mapbox-iOS-SDK-symbols.podspec
#	platform/ios/Mapbox-iOS-SDK.podspec
#	platform/ios/app/MBXViewController.m
#	src/mbgl/renderer/layers/render_custom_layer.cpp
#	src/mbgl/style/conversion/filter.cpp
#	src/mbgl/style/expression/interpolate.cpp
#	src/mbgl/style/expression/value.cpp
#	test/style/filter.test.cpp
This commit is contained in:
Fabian Guerra
2018-04-23 10:44:02 -04:00
558 changed files with 18675 additions and 28112 deletions

4
.gitmodules vendored
View File

@@ -7,3 +7,7 @@
[submodule "mapbox-gl-js"]
path = mapbox-gl-js
url = https://github.com/mapbox/mapbox-gl-js.git
[submodule "platform/ios/vendor/mapbox-events-ios"]
path = platform/ios/vendor/mapbox-events-ios
url = https://github.com/mapbox/mapbox-events-ios.git
branch = boundsj-add-namespace-header

View File

@@ -7,6 +7,7 @@ option(WITH_COVERAGE "Enable coverage reports" OFF)
option(WITH_OSMESA "Use OSMesa headless backend" OFF)
option(WITH_EGL "Use EGL backend" OFF)
option(WITH_NODEJS "Download test dependencies like NPM and Node.js" ON)
option(WITH_ERROR "Add -Werror flag to build (turns warnings into errors)" ON)
include(cmake/mbgl.cmake)
include(cmake/mason.cmake)
@@ -74,8 +75,14 @@ endif(WITH_COVERAGE)
set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebugInfo Sanitize)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -fPIC -fvisibility=hidden -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Werror -Wno-variadic-macros -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden -Wall -Wextra -Wshadow -Werror -Wno-variadic-macros -Wno-unknown-pragmas")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -fPIC -fvisibility=hidden -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-variadic-macros -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden -Wall -Wextra -Wshadow -Wno-variadic-macros -Wno-unknown-pragmas")
if (WITH_ERROR)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif()
if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# -Wno-error=unused-command-line-argument is required due to https://llvm.org/bugs/show_bug.cgi?id=7798
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument")

View File

@@ -45,7 +45,7 @@ ifeq ($(V), 1)
export XCPRETTY
NINJA_ARGS ?= -v
else
export XCPRETTY ?= | xcpretty
export XCPRETTY ?= | tee '$(shell pwd)/build/xcodebuild-$(shell date +"%Y-%m-%d_%H%M%S").log' | xcpretty
NINJA_ARGS ?=
endif
@@ -235,13 +235,17 @@ ios-test: $(IOS_PROJ_PATH)
ios-integration-test: $(IOS_PROJ_PATH)
set -o pipefail && $(IOS_XCODEBUILD_SIM) -scheme 'Integration Test Harness' test $(XCPRETTY)
.PHONY: ios-sanitize
ios-sanitize: $(IOS_PROJ_PATH)
set -o pipefail && $(IOS_XCODEBUILD_SIM) -scheme 'CI' -enableThreadSanitizer YES -enableUndefinedBehaviorSanitizer YES test $(XCPRETTY)
.PHONY: ios-sanitize-address
ios-sanitize-address: $(IOS_PROJ_PATH)
set -o pipefail && $(IOS_XCODEBUILD_SIM) -scheme 'CI' -enableAddressSanitizer YES test $(XCPRETTY)
.PHONY: ios-sanitize-thread
ios-sanitize-thread: $(IOS_PROJ_PATH)
set -o pipefail && $(IOS_XCODEBUILD_SIM) -scheme 'CI' -enableThreadSanitizer YES test $(XCPRETTY)
.PHONY: ios-static-analyzer
ios-static-analyzer: $(IOS_PROJ_PATH)
set -o pipefail && $(IOS_XCODEBUILD_SIM) analyze -scheme 'CI' test $(XCPRETTY)
.PHONY: ipackage
ipackage: $(IOS_PROJ_PATH)

View File

@@ -10,8 +10,8 @@ This repository hosts the cross-platform Mapbox GL Native library, plus convenie
| --------------------------------------- | ---------------------------------- | ---------------------------------------- |
| [Mapbox GL Native](INSTALL.md) | C++14 | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-native/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-native?branch=master) |
| [Mapbox Maps SDK for Android](platform/android/) | Java | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) |
| [Mapbox Maps SDK for iOS](platform/ios/) | Objective-C or Swift | [![Bitrise](https://www.bitrise.io/app/7514e4cf3da2cc57.svg?token=OwqZE5rSBR9MVWNr_lf4sA&branch=master)](https://www.bitrise.io/app/7514e4cf3da2cc57) |
| [Mapbox Maps SDK for macOS](platform/macos/) | Objective-C, Swift, or AppleScript | [![Bitrise](https://www.bitrise.io/app/155ef7da24b38dcd.svg?token=4KSOw_gd6WxTnvGE2rMttg&branch=master)](https://www.bitrise.io/app/155ef7da24b38dcd) |
| [Mapbox Maps SDK for iOS](platform/ios/) | Objective-C or Swift | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) |
| [Mapbox Maps SDK for macOS](platform/macos/) | Objective-C, Swift, or AppleScript | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) |
| [node-mapbox-gl-native](platform/node/) | Node.js | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) |
| [Mapbox Maps SDK for Qt](platform/qt) | C++03 | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) [![AppVeyor CI build status](https://ci.appveyor.com/api/projects/status/3q12kbcooc6df8uc?svg=true)](https://ci.appveyor.com/project/Mapbox/mapbox-gl-native) |
@@ -27,4 +27,7 @@ Additional Mapbox GL Native–based libraries for **hybrid applications** are de
If your platform or hybrid application framework isn’t listed here, consider embedding [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) using the standard Web capabilities on your platform.
## License
Mapbox GL Native is licensed under the [3-Clause BSD license](LICENSE.md). The licenses of its dependencies are tracked via [FOSSA](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fmapbox-gl-native):
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fmapbox-gl-native.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fmapbox-gl-native)

View File

@@ -21,6 +21,7 @@ int main(int argc, char *argv[]) {
args::ValueFlag<std::string> tokenValue(argumentParser, "key", "Mapbox access token", {'t', "token"});
args::ValueFlag<std::string> styleValue(argumentParser, "URL", "Map stylesheet", {'s', "style"});
args::ValueFlag<std::string> outputValue(argumentParser, "file", "Output database file name", {'o', "output"});
args::ValueFlag<std::string> apiBaseValue(argumentParser, "URL", "API Base URL", {'a', "apiBaseURL"});
args::ValueFlag<double> northValue(argumentParser, "degrees", "North latitude", {"north"});
args::ValueFlag<double> westValue(argumentParser, "degrees", "West longitude", {"west"});
@@ -60,6 +61,8 @@ int main(int argc, char *argv[]) {
const char* tokenEnv = getenv("MAPBOX_ACCESS_TOKEN");
const std::string token = tokenValue ? args::get(tokenValue) : (tokenEnv ? tokenEnv : std::string());
const std::string apiBaseURL = apiBaseValue ? args::get(apiBaseValue) : mbgl::util::API_BASE_URL;
using namespace mbgl;
@@ -68,6 +71,7 @@ int main(int argc, char *argv[]) {
std::unique_ptr<OfflineRegion> region;
fileSource.setAccessToken(token);
fileSource.setAPIBaseURL(apiBaseURL);
LatLngBounds boundingBox = LatLngBounds::hull(LatLng(north, west), LatLng(south, east));
OfflineTilePyramidRegionDefinition definition(style, boundingBox, minZoom, maxZoom, pixelRatio);

View File

@@ -32,8 +32,9 @@ workflows:
- linux-gcc5-release-qt4
- linux-gcc5-release-qt5
- ios-debug
#- ios-sanitize-address
- ios-sanitize-thread
- ios-sanitize
- ios-sanitize-address
- ios-static-analyzer
- ios-release:
filters:
tags:
@@ -150,8 +151,7 @@ step-library:
run:
name: Install macOS dependencies
command: |
brew install cmake
brew install ccache
brew install cmake ccache
- &install-macos-node4-dependencies
run:
@@ -171,14 +171,12 @@ step-library:
run:
name: Install macOS Qt dependencies
command: |
sudo chown -R $USER /usr/local
brew install qt
brew link qt --force
brew linkapps qt
export HOMEBREW_QT5_CELLAR=$(brew --cellar qt)
export HOMEBREW_QT5_VERSION=$(brew list --versions qt | rev | cut -d' ' -f1 | rev)
ln -s $HOMEBREW_QT5_CELLAR/$HOMEBREW_QT5_VERSION/mkspecs /usr/local/mkspecs
ln -s $HOMEBREW_QT5_CELLAR/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins
sudo ln -s $HOMEBREW_QT5_CELLAR/$HOMEBREW_QT5_VERSION/mkspecs /usr/local/mkspecs
sudo ln -s $HOMEBREW_QT5_CELLAR/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins
- &run-node-macos-tests
run:
@@ -223,6 +221,18 @@ step-library:
path: mapbox-gl-js/test/integration/render-tests/index-recycle-map.html
destination: render-tests
- &collect-xcode-build-logs
run:
name: Collect Xcode build logs
when: always
command: |
export XCODE_LOG_DIR=build/logs
mkdir -p $XCODE_LOG_DIR
cp build/*.log $XCODE_LOG_DIR
- &upload-xcode-build-logs
store_artifacts:
path: build/logs
jobs:
nitpick:
docker:
@@ -395,6 +405,9 @@ jobs:
- run:
name: Build package
command: make apackage
- run:
name: Build release Test App
command: make android
- *show-ccache-stats
- *save-cache
- *save-gradle-cache
@@ -409,7 +422,7 @@ jobs:
- deploy:
name: Publish to Maven
command: |
if [ "${CIRCLE_BRANCH}" == "master" ]; then make run-android-upload-archives ; fi
if [ "${CIRCLE_BRANCH}" == "release-boba" ]; then make run-android-upload-archives ; fi
# ------------------------------------------------------------------------------
@@ -706,7 +719,7 @@ jobs:
# ------------------------------------------------------------------------------
ios-debug:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -727,11 +740,34 @@ jobs:
command: scripts/nitpick/generated-code.js darwin
- *show-ccache-stats
- *save-cache
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
ios-sanitize:
macos:
xcode: "9.3.0"
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
steps:
- checkout
- *install-macos-dependencies
- *generate-cache-key
- *restore-cache
- *reset-ccache-stats
- run:
name: Build and run SDK unit tests with thread and undefined behavior sanitizers
command: make ios-sanitize
- *show-ccache-stats
- *save-cache
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
ios-sanitize-address:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -746,11 +782,13 @@ jobs:
command: make ios-sanitize-address
- *show-ccache-stats
- *save-cache
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
ios-sanitize-thread:
ios-static-analyzer:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -761,15 +799,17 @@ jobs:
- *restore-cache
- *reset-ccache-stats
- run:
name: Build and run SDK unit tests with thread sanitizer
command: make ios-sanitize-thread
name: Build and run SDK unit tests with the static analyzer
command: make ios-static-analyzer
- *show-ccache-stats
- *save-cache
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
ios-release:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
HOMEBREW_NO_AUTO_UPDATE: 1
shell: /bin/bash --login -eo pipefail
@@ -797,7 +837,7 @@ jobs:
# ------------------------------------------------------------------------------
macos-debug:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -820,6 +860,8 @@ jobs:
- store_artifacts:
path: test/fixtures
destination: test/fixtures
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
macos-debug-qt5:
@@ -849,7 +891,7 @@ jobs:
# ------------------------------------------------------------------------------
macos-release-node4:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: RelWithDebInfo
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -866,11 +908,13 @@ jobs:
- *run-node-macos-tests
- *publish-node-package
- *upload-render-tests
- *collect-xcode-build-logs
- *upload-xcode-build-logs
# ------------------------------------------------------------------------------
macos-release-node6:
macos:
xcode: "9.2.0"
xcode: "9.3.0"
environment:
BUILDTYPE: RelWithDebInfo
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -887,3 +931,5 @@ jobs:
- *run-node-macos-tests
- *publish-node-package
- *upload-render-tests
- *collect-xcode-build-logs
- *upload-xcode-build-logs

View File

@@ -410,7 +410,6 @@ set(MBGL_CORE_FILES
include/mbgl/style/conversion/coordinate.hpp
include/mbgl/style/conversion/custom_geometry_source_options.hpp
include/mbgl/style/conversion/data_driven_property_value.hpp
include/mbgl/style/conversion/expression.hpp
include/mbgl/style/conversion/filter.hpp
include/mbgl/style/conversion/function.hpp
include/mbgl/style/conversion/geojson.hpp
@@ -458,6 +457,7 @@ set(MBGL_CORE_FILES
include/mbgl/style/expression/interpolate.hpp
include/mbgl/style/expression/is_constant.hpp
include/mbgl/style/expression/is_expression.hpp
include/mbgl/style/expression/length.hpp
include/mbgl/style/expression/let.hpp
include/mbgl/style/expression/literal.hpp
include/mbgl/style/expression/match.hpp
@@ -480,6 +480,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/expression/interpolate.cpp
src/mbgl/style/expression/is_constant.cpp
src/mbgl/style/expression/is_expression.cpp
src/mbgl/style/expression/length.cpp
src/mbgl/style/expression/let.cpp
src/mbgl/style/expression/literal.cpp
src/mbgl/style/expression/match.cpp

View File

@@ -110,7 +110,7 @@ endfunction()
if(MBGL_PLATFORM STREQUAL "ios")
execute_process(
COMMAND git submodule update --init platform/ios/vendor/SMCalloutView platform/ios/uitest/KIF platform/ios/uitest/OHHTTPStubs
COMMAND git submodule update --init platform/ios/vendor/mapbox-events-ios platform/ios/uitest/KIF platform/ios/uitest/OHHTTPStubs
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
endif()

View File

@@ -47,10 +47,10 @@ protected:
// as a matched pair, exclusively through BackendScope, in two situations:
//
// 1. When releasing GL resources during Renderer destruction
// (Including calling CustomLayerDeinitializeFunction during RenderCustomLayer destruction)
// (Including calling CustomLayerHost::deinitialize during RenderCustomLayer destruction)
// 2. When renderering through Renderer::render()
// (Including calling CustomLayerDeinitializeFunction for newly added custom layers and
// CustomLayerDeinitializeFunction on layer removal)
// (Including calling CustomLayerHost::initialize for newly added custom layers and
// CustomLayerHost::deinitialize on layer removal)
virtual void activate() = 0;
virtual void deactivate() = 0;

View File

@@ -4,10 +4,12 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/conversion/expression.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/literal.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <unordered_set>
@@ -20,24 +22,35 @@ template <class T>
struct Converter<DataDrivenPropertyValue<T>> {
optional<DataDrivenPropertyValue<T>> operator()(const Convertible& value, Error& error) const {
using namespace mbgl::style::expression;
if (isUndefined(value)) {
return DataDrivenPropertyValue<T>();
} else if (expression::isExpression(value)) {
optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(
value,
error,
valueTypeToExpressionType<T>());
} else if (isExpression(value)) {
ParsingContext ctx(valueTypeToExpressionType<T>());
ParseResult expression = ctx.parseLayerPropertyExpression(value);
if (!expression) {
error = { ctx.getCombinedErrors() };
return {};
}
if (isFeatureConstant(**expression)) {
bool featureConstant = isFeatureConstant(**expression);
bool zoomConstant = isZoomConstant(**expression);
if (featureConstant && !zoomConstant) {
return DataDrivenPropertyValue<T>(CameraFunction<T>(std::move(*expression)));
} else if (isZoomConstant(**expression)) {
} else if (!featureConstant && zoomConstant) {
return DataDrivenPropertyValue<T>(SourceFunction<T>(std::move(*expression)));
} else {
} else if (!featureConstant && !zoomConstant) {
return DataDrivenPropertyValue<T>(CompositeFunction<T>(std::move(*expression)));
} else {
auto literal = dynamic_cast<Literal*>(expression->get());
assert(literal);
optional<T> constant = fromExpressionValue<T>(literal->getValue());
if (!constant) {
return {};
}
return DataDrivenPropertyValue<T>(*constant);
}
} else if (!isObject(value)) {
optional<T> constant = convert<T>(value, error);

View File

@@ -1,39 +0,0 @@
#pragma once
#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/expression/type.hpp>
#include <mbgl/style/conversion.hpp>
#include <memory>
namespace mbgl {
namespace style {
namespace conversion {
using namespace mbgl::style::expression;
template<> struct Converter<std::unique_ptr<Expression>> {
optional<std::unique_ptr<Expression>> operator()(const Convertible& value, Error& error, type::Type expected) const {
ParsingContext ctx(optional<type::Type> {expected});
ParseResult parsed = ctx.parse(value);
if (parsed) {
return std::move(*parsed);
}
std::string combinedError;
for (const ParsingError& parsingError : ctx.getErrors()) {
if (combinedError.size() > 0) {
combinedError += "\n";
}
if (parsingError.key.size() > 0) {
combinedError += parsingError.key + ": ";
}
combinedError += parsingError.message;
}
error = { combinedError };
return {};
};
};
} // namespace conversion
} // namespace style
} // namespace mbgl

View File

@@ -4,11 +4,11 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/conversion/expression.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
namespace mbgl {
namespace style {
@@ -17,11 +17,14 @@ namespace conversion {
template <>
struct Converter<HeatmapColorPropertyValue> {
optional<HeatmapColorPropertyValue> operator()(const Convertible& value, Error& error) const {
using namespace mbgl::style::expression;
if (isUndefined(value)) {
return HeatmapColorPropertyValue();
} else if (isExpression(value)) {
optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(value, error, expression::type::Color);
ParsingContext ctx(type::Color);
ParseResult expression = ctx.parseLayerPropertyExpression(value);
if (!expression) {
error = { ctx.getCombinedErrors() };
return {};
}
assert(*expression);

View File

@@ -4,11 +4,11 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/conversion/expression.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
namespace mbgl {
namespace style {
@@ -17,13 +17,18 @@ namespace conversion {
template <class T>
struct Converter<PropertyValue<T>> {
optional<PropertyValue<T>> operator()(const Convertible& value, Error& error) const {
using namespace mbgl::style::expression;
if (isUndefined(value)) {
return PropertyValue<T>();
} else if (isExpression(value)) {
optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(value, error, valueTypeToExpressionType<T>());
ParsingContext ctx(valueTypeToExpressionType<T>());
ParseResult expression = ctx.parseLayerPropertyExpression(value);
if (!expression) {
error = { ctx.getCombinedErrors() };
return {};
}
if (isFeatureConstant(**expression)) {
return { CameraFunction<T>(std::move(*expression)) };
} else {

View File

@@ -50,6 +50,15 @@ public:
return !value.template is<CameraFunction<T>>() && !value.template is<CompositeFunction<T>>();
}
bool isExpression() const {
return value.match(
[] (const Undefined&) { return false; },
[] (const T&) { return false; },
[] (const CameraFunction<T>& fn) { return fn.isExpression; },
[] (const SourceFunction<T>& fn) { return fn.isExpression; },
[] (const CompositeFunction<T>& fn) { return fn.isExpression; });
}
template <class... Ts>
auto match(Ts&&... ts) const {
return value.match(std::forward<Ts>(ts)...);

View File

@@ -0,0 +1,32 @@
#pragma once
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <memory>
#include <vector>
namespace mbgl {
namespace style {
namespace expression {
class Length : public Expression {
public:
Length(std::unique_ptr<Expression> input);
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
std::vector<optional<Value>> possibleOutputs() const override;
std::string getOperator() const override { return "length"; }
private:
std::unique_ptr<Expression> input;
};
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -70,6 +70,9 @@ public:
mbgl::Value serialize() const override;
std::string getOperator() const override { return "var"; }
const std::shared_ptr<Expression>& getBoundExpression() const { return value; }
private:
std::string name;
std::shared_ptr<Expression> value;

View File

@@ -40,6 +40,10 @@ public:
std::vector<optional<Value>> possibleOutputs() const override {
return {{ value }};
}
Value getValue() const {
return value;
}
mbgl::Value serialize() const override;
std::string getOperator() const override { return "literal"; }

View File

@@ -55,7 +55,7 @@ class ParsingContext {
public:
ParsingContext() : errors(std::make_shared<std::vector<ParsingError>>()) {}
ParsingContext(std::string key_) : key(std::move(key_)), errors(std::make_shared<std::vector<ParsingError>>()) {}
explicit ParsingContext(optional<type::Type> expected_)
explicit ParsingContext(type::Type expected_)
: expected(std::move(expected_)),
errors(std::make_shared<std::vector<ParsingError>>())
{}
@@ -67,6 +67,7 @@ public:
std::string getKey() const { return key; }
optional<type::Type> getExpected() const { return expected; }
const std::vector<ParsingError>& getErrors() const { return *errors; }
const std::string getCombinedErrors() const;
enum TypeAnnotationOption {
includeTypeAnnotations,
@@ -74,16 +75,21 @@ public:
};
/*
Parse the given style-spec JSON value into an Expression object.
Specifically, this function is responsible for determining the expression
type (either Literal, or the one named in value[0]) and dispatching to the
appropriate ParseXxxx::parse(const V&, ParsingContext) method.
Parse the given style-spec JSON value as an expression.
*/
ParseResult parse(const mbgl::style::conversion::Convertible& value,
TypeAnnotationOption typeAnnotationOption = includeTypeAnnotations);
ParseResult parseExpression(const mbgl::style::conversion::Convertible& value,
TypeAnnotationOption typeAnnotationOption = includeTypeAnnotations);
/*
Parse a child expression.
Parse the given style-spec JSON value as an expression intended to be used
in a layout or paint property. This entails checking additional constraints
that exist in that context but not, e.g., for filters.
*/
ParseResult parseLayerPropertyExpression(const mbgl::style::conversion::Convertible& value,
TypeAnnotationOption typeAnnotationOption = includeTypeAnnotations);
/*
Parse a child expression. For use by individual Expression::parse() methods.
*/
ParseResult parse(const mbgl::style::conversion::Convertible&,
std::size_t,
@@ -91,7 +97,7 @@ public:
TypeAnnotationOption typeAnnotationOption = includeTypeAnnotations);
/*
Parse a child expression.
Parse a child expression. For use by individual Expression::parse() methods.
*/
ParseResult parse(const mbgl::style::conversion::Convertible&,
std::size_t index,
@@ -141,6 +147,16 @@ private:
errors(std::move(errors_))
{}
/*
Parse the given style-spec JSON value into an Expression object.
Specifically, this function is responsible for determining the expression
type (either Literal, or the one named in value[0]) and dispatching to the
appropriate ParseXxxx::parse(const V&, ParsingContext) method.
*/
ParseResult parse(const mbgl::style::conversion::Convertible& value,
TypeAnnotationOption typeAnnotationOption = includeTypeAnnotations);
std::string key;
optional<type::Type> expected;
std::shared_ptr<detail::Scope> scope;

View File

@@ -27,15 +27,16 @@ public:
IntervalStops<T>>>;
CameraFunction(std::unique_ptr<expression::Expression> expression_)
: expression(std::move(expression_)),
: isExpression(true),
expression(std::move(expression_)),
zoomCurve(expression::findZoomCurveChecked(expression.get()))
{
assert(!expression::isZoomConstant(*expression));
assert(expression::isFeatureConstant(*expression));
}
CameraFunction(Stops stops_)
: stops(std::move(stops_)),
CameraFunction(const Stops& stops)
: isExpression(false),
expression(stops.match([&] (const auto& s) {
return expression::Convert::toExpression(s);
})),
@@ -76,12 +77,10 @@ public:
}
bool useIntegerZoom = false;
bool isExpression;
const expression::Expression& getExpression() const { return *expression; }
// retained for compatibility with pre-expression function API
Stops stops;
private:
std::shared_ptr<expression::Expression> expression;
const variant<const expression::InterpolateBase*, const expression::Step*> zoomCurve;

View File

@@ -51,16 +51,16 @@ public:
CompositeCategoricalStops<T>>>;
CompositeFunction(std::unique_ptr<expression::Expression> expression_)
: expression(std::move(expression_)),
: isExpression(true),
expression(std::move(expression_)),
zoomCurve(expression::findZoomCurveChecked(expression.get()))
{
assert(!expression::isZoomConstant(*expression));
assert(!expression::isFeatureConstant(*expression));
}
CompositeFunction(std::string property_, Stops stops_, optional<T> defaultValue_ = {})
: property(std::move(property_)),
stops(std::move(stops_)),
CompositeFunction(const std::string& property, const Stops& stops, optional<T> defaultValue_ = {})
: isExpression(false),
defaultValue(std::move(defaultValue_)),
expression(stops.match([&] (const auto& s) {
return expression::Convert::toExpression(property, s);
@@ -113,12 +113,11 @@ public:
const expression::Expression& getExpression() const { return *expression; }
std::string property;
Stops stops;
optional<T> defaultValue;
bool useIntegerZoom = false;
bool isExpression;
private:
optional<T> defaultValue;
std::shared_ptr<expression::Expression> expression;
const variant<const expression::InterpolateBase*, const expression::Step*> zoomCurve;
};

View File

@@ -30,15 +30,15 @@ public:
IdentityStops<T>>>;
SourceFunction(std::unique_ptr<expression::Expression> expression_)
: expression(std::move(expression_))
: isExpression(true),
expression(std::move(expression_))
{
assert(expression::isZoomConstant(*expression));
assert(!expression::isFeatureConstant(*expression));
}
SourceFunction(std::string property_, Stops stops_, optional<T> defaultValue_ = {})
: property(std::move(property_)),
stops(std::move(stops_)),
SourceFunction(const std::string& property, const Stops& stops, optional<T> defaultValue_ = {})
: isExpression(false),
defaultValue(std::move(defaultValue_)),
expression(stops.match([&] (const IdentityStops<T>&) {
return expression::Convert::fromIdentityFunction(expression::valueTypeToExpressionType<T>(), property);
@@ -67,15 +67,12 @@ public:
}
bool useIntegerZoom = false;
bool isExpression;
const expression::Expression& getExpression() const { return *expression; }
// retained for compatibility with pre-expression function API
std::string property;
Stops stops;
optional<T> defaultValue;
private:
optional<T> defaultValue;
std::shared_ptr<expression::Expression> expression;
};

View File

@@ -2,20 +2,13 @@
#include <mbgl/style/layer.hpp>
#include <array>
namespace mbgl {
namespace style {
/**
* Initialize any GL state needed by the custom layer. This method is called once, from the
* main thread, at a point when the GL context is active but before rendering for the first
* time.
*
* Resources that are acquired in this method must be released in the UninitializeFunction.
*/
using CustomLayerInitializeFunction = void (*)(void* context);
/**
* Parameters that define the current camera position for a CustomLayerRenderFunction.
* Parameters that define the current camera position for a `CustomLayerHost::render()` function.
*/
struct CustomLayerRenderParameters {
double width;
@@ -26,48 +19,52 @@ struct CustomLayerRenderParameters {
double bearing;
double pitch;
double fieldOfView;
std::array<double, 16> projectionMatrix;
};
/**
* Render the layer. This method is called once per frame. The implementation should not make
* any assumptions about the GL state (other than that the correct context is active). It may
* make changes to the state, and is not required to reset values such as the depth mask, stencil
* mask, and corresponding test flags to their original values.
* Make sure that you are drawing your fragments with a z value of 1 to take advantage of the
* opaque fragment culling in case there are opaque layers above your custom layer.
*/
using CustomLayerRenderFunction = void (*)(void* context, const CustomLayerRenderParameters&);
class CustomLayerHost {
public:
virtual ~CustomLayerHost() = default;
/**
* Initialize any GL state needed by the custom layer. This method is called once, from the
* main thread, at a point when the GL context is active but before rendering for the first
* time.
*
* Resources that are acquired in this method must be released in the `deinitialize` function.
*/
virtual void initialize() = 0;
/**
* Called when the system has destroyed the underlying GL context. The
* `CustomLayerDeinitializeFunction` will not be called in this case, however
* `CustomLayerInitializeFunction` will be called instead to prepare for a new render.
*
*/
using CustomLayerContextLostFunction = void (*)(void* context);
/**
* Render the layer. This method is called once per frame. The implementation should not make
* any assumptions about the GL state (other than that the correct context is active). It may
* make changes to the state, and is not required to reset values such as the depth mask, stencil
* mask, and corresponding test flags to their original values.
* Make sure that you are drawing your fragments with a z value of 1 to take advantage of the
* opaque fragment culling in case there are opaque layers above your custom layer.
*/
virtual void render(const CustomLayerRenderParameters&) = 0;
/**
* Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This
* method is called once, from the main thread, at a point when the GL context is active.
*
* Note that it may be called even when the InitializeFunction has not been called.
*/
using CustomLayerDeinitializeFunction = void (*)(void* context);
/**
* Called when the system has destroyed the underlying GL context. The
* `deinitialize` function will not be called in this case, however
* `initialize` will be called instead to prepare for a new render.
*
*/
virtual void contextLost() = 0;
/**
* Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This
* method is called once, from the main thread, at a point when the GL context is active.
*
* Note that it may be called even when the `initialize` function has not been called.
*/
virtual void deinitialize() = 0;
};
class CustomLayer : public Layer {
public:
CustomLayer(const std::string& id,
CustomLayerInitializeFunction,
CustomLayerRenderFunction,
CustomLayerContextLostFunction,
CustomLayerDeinitializeFunction,
void* context);
CustomLayer(const std::string& id,
CustomLayerInitializeFunction,
CustomLayerRenderFunction,
CustomLayerDeinitializeFunction,
void* context);
std::unique_ptr<CustomLayerHost> host);
~CustomLayer() final;

View File

@@ -4,6 +4,7 @@
#include <cassert>
#include <string>
#include <array>
namespace mbgl {
@@ -37,6 +38,7 @@ public:
static optional<Color> parse(const std::string&);
std::string stringify() const;
std::array<double, 4> toArray() const;
};
inline bool operator==(const Color& colorA, const Color& colorB) {

View File

@@ -8,11 +8,6 @@ dependencies {
implementation dependenciesList.supportFragmentV4
implementation dependenciesList.timber
implementation dependenciesList.okhttp3
compileOnly(dependenciesList.lost) {
exclude group: 'com.google.guava'
exclude group: 'com.android.support'
}
testImplementation dependenciesList.lost
testImplementation dependenciesList.junit
testImplementation dependenciesList.mockito
testImplementation dependenciesList.robolectric
@@ -111,8 +106,8 @@ android {
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
lintOptions {

View File

@@ -1,5 +1,5 @@
GROUP=com.mapbox.mapboxsdk
VERSION_NAME=7.0.0-SNAPSHOT
VERSION_NAME=6.1.0-SNAPSHOT
POM_DESCRIPTION=Mapbox GL Android SDK
POM_URL=https://github.com/mapbox/mapbox-gl-native
@@ -18,4 +18,3 @@ POM_PACKAGING=aar
# Only build native dependencies for the current ABI
# See https://code.google.com/p/android/issues/detail?id=221098#c20
android.buildOnlyTargetAbi=true

View File

@@ -2,17 +2,42 @@
# in ../sdk/tools/proguard/proguard-android.txt,
# contents of this file will be appended into proguard-android.txt
-keepattributes Signature, *Annotation*, EnclosingMethod
-keep class almeros.android.multitouch.gesturedetectors.** { *; }
# config for the SDK
-keep class com.mapbox.mapboxsdk.** { *; }
-keep interface com.mapbox.mapboxsdk.** { *; }
-keep class com.mapbox.services.android.telemetry.** { *; }
-keep class com.mapbox.services.commons.** { *;}
-keep class com.google.gson.** { *; }
# config for okhttp 3.8.0, https://github.com/square/okhttp/pull/3354
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
-dontwarn javax.annotation.**
-dontnote okhttp3.**
# config for optional location provider https://github.com/mapbox/mapbox-gl-native/issues/10960
-dontwarn com.mapzen.android.lost.api**
# config for mapbox-android-telemetry:3.0.0-beta.1
-keep class com.mapbox.android.telemetry.** { *; }
-dontwarn com.mapbox.android.core.location.MockLocationEngine
-dontwarn com.mapbox.android.core.location.MockLocationEngine$LocationUpdateRunnable
-dontwarn java.awt.Color
-dontwarn com.mapzen.android.lost.api**
-dontwarn org.conscrypt.OpenSSLProvider
-dontwarn org.conscrypt.Conscrypt
# config for mapbox-sdk-geojson:3.0.1
-keep class com.mapbox.geojson.** { *; }
-keep class com.google.gson.** { *; }
-dontnote com.google.gson.internal.UnsafeAllocator
# config for mapbox-android-gestures:0.0.1-20180228.152340-13
-dontnote com.mapbox.android.gestures.*
# config for additional warnings
-keep class com.google.android.gms.dynamite.descriptors.com.google.android.gms.flags.ModuleDescriptor { java.lang.String MODULE_ID; }
-keep class com.google.android.gms.dynamite.descriptors.com.google.android.gms.flags.ModuleDescriptor { int MODULE_VERSION; }
-keep class com.google.android.gms.dynamite.DynamiteModule$DynamiteLoaderClassLoader { java.lang.ClassLoader sClassLoader; }
-dontnote com.google.devtools.build.android.desugar.runtime.ThrowableExtension
-dontnote org.robolectric.Robolectric
-dontnote libcore.io.Memory
-dontnote com.google.protobuf.ExtensionRegistry
-dontnote com.google.protobuf.Extension
-dontnote android.net.**
-dontnote org.apache.http.**
-dontwarn com.sun.xml.internal.ws.spi.db.**

View File

@@ -1,20 +1,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mapbox.mapboxsdk">
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="false" /> <!-- Implied by ACCESS_WIFI_STATE. -->
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<uses-feature
android:name="android.hardware.wifi"
android:required="false"/> <!-- Implied by ACCESS_WIFI_STATE. -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-sdk tools:overrideLibrary="com.mapzen.lost"/>
<application>
<!-- Include the telemetry service to simplify set up (https://www.mapbox.com/telemetry) -->
<service android:name="com.mapbox.services.android.telemetry.service.TelemetryService"/>
</application>
</manifest>

View File

@@ -8,11 +8,9 @@ import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.text.TextUtils;
import com.mapbox.android.core.location.LocationEngine;
import com.mapbox.android.core.location.LocationEnginePriority;
import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException;
import com.mapbox.mapboxsdk.maps.Telemetry;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
/**
@@ -31,7 +29,6 @@ public final class Mapbox {
private Context context;
private String accessToken;
private Boolean connected;
private LocationEngine locationEngine;
/**
* Get an instance of Mapbox.
@@ -47,21 +44,18 @@ public final class Mapbox {
public static synchronized Mapbox getInstance(@NonNull Context context, @NonNull String accessToken) {
if (INSTANCE == null) {
Context appContext = context.getApplicationContext();
LocationEngineProvider locationEngineProvider = new LocationEngineProvider(context);
LocationEngine locationEngine = locationEngineProvider.obtainBestLocationEngineAvailable();
INSTANCE = new Mapbox(appContext, accessToken, locationEngine);
locationEngine.setPriority(LocationEnginePriority.NO_POWER);
INSTANCE = new Mapbox(appContext, accessToken);
Telemetry.initialize();
ConnectivityReceiver.instance(appContext);
}
return INSTANCE;
}
Mapbox(@NonNull Context context, @NonNull String accessToken, LocationEngine locationEngine) {
Mapbox(@NonNull Context context, @NonNull String accessToken) {
this.context = context;
this.accessToken = accessToken;
this.locationEngine = locationEngine;
}
/**
@@ -134,14 +128,4 @@ public final class Mapbox {
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
/**
* Returns the location engine used by the SDK.
*
* @return the location engine configured
*/
// TODO Do we need to expose this?
public static LocationEngine getLocationEngine() {
return INSTANCE.locationEngine;
}
}

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android Attribution API classes.
*/
package com.mapbox.mapboxsdk.attribution;

View File

@@ -148,6 +148,26 @@ public final class CameraUpdateFactory {
return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
}
/**
* Returns a CameraUpdate that moves the camera viewpoint to a particular bearing.
*
* @param bearing Bearing to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate bearingTo(double bearing) {
return new CameraPositionUpdate(bearing, null, -1, -1);
}
/**
* Returns a CameraUpdate that moves the camera viewpoint to a particular tilt.
*
* @param tilt Tilt to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate tiltTo(double tilt) {
return new CameraPositionUpdate(-1, null, tilt, -1);
}
//
// CameraUpdate types
//

View File

@@ -121,23 +121,13 @@ public class MapboxConstants {
public static final String STATE_HAS_SAVED_STATE = "mapbox_savedState";
public static final String STATE_CAMERA_POSITION = "mapbox_cameraPosition";
public static final String STATE_ZOOM_ENABLED = "mapbox_zoomEnabled";
public static final String STATE_ZOOM_ENABLED_CHANGE = "mapbox_zoomEnabledChange";
public static final String STATE_SCROLL_ENABLED = "mapbox_scrollEnabled";
public static final String STATE_SCROLL_ENABLED_CHANGE = "mapbox_scrollEnabledChange";
public static final String STATE_ROTATE_ENABLED = "mapbox_rotateEnabled";
public static final String STATE_ROTATE_ENABLED_CHANGE = "mapbox_rotateEnabledChange";
public static final String STATE_TILT_ENABLED = "mapbox_tiltEnabled";
public static final String STATE_TILT_ENABLED_CHANGE = "mapbox_tiltEnabledChange";
public static final String STATE_ZOOM_CONTROLS_ENABLED = "mapbox_zoomControlsEnabled";
public static final String STATE_DOUBLE_TAP_ENABLED = "mapbox_doubleTapEnabled";
public static final String STATE_DOUBLE_TAP_ENABLED_CHANGE = "mapbox_doubleTapEnabledChange";
public static final String STATE_DEBUG_ACTIVE = "mapbox_debugActive";
public static final String STATE_STYLE_URL = "mapbox_styleUrl";
public static final String STATE_MY_LOCATION_ENABLED = "mapbox_myLocationEnabled";
public static final String STATE_MY_LOCATION_TRACKING_MODE = "mapbox_myLocationTracking";
public static final String STATE_MY_BEARING_TRACKING_MODE = "mapbox_myBearingTracking";
public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "mapbox_myLocationTrackingDismiss";
public static final String STATE_MY_BEARING_TRACKING_DISMISS = "mapbox_myBearingTrackingDismiss";
public static final String STATE_COMPASS_ENABLED = "mapbox_compassEnabled";
public static final String STATE_COMPASS_GRAVITY = "mapbox_compassGravity";
public static final String STATE_COMPASS_MARGIN_LEFT = "mapbox_compassMarginLeft";
@@ -158,20 +148,12 @@ public class MapboxConstants {
public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "mapbox_attrMarginRight";
public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "mapbox_atrrMarginBottom";
public static final String STATE_ATTRIBUTION_ENABLED = "mapbox_atrrEnabled";
public static final String STATE_LOCATION_CHANGE_ANIMATION_ENABLED = "mapbox_locationChangeAnimationEnabled";
public static final String STATE_USING_CUSTOM_LOCATION_SOURCE = "mapbox_usingCustomLocationSource";
public static final String STATE_LOCATION_VIEW_ENABLED = "mapbox_locViewEnabled";
public static final String STATE_LOCATION_VIEW_FOREGROUND_DRAWABLE = "mapbox_locViewForegroundDrawable";
public static final String STATE_LOCATION_VIEW_FOREGROUND_BEARING_DRAWABLE = "mapbox_locViewBearingDrawable";
public static final String STATE_LOCATION_VIEW_FOREGROUND_TINT_COLOR = "mapbox_locViewForegroundTintColor";
public static final String STATE_LOCATION_VIEW_BACKGROUND_DRAWABLE = "mapbox_locViewBackgroundDrawable";
public static final String STATE_LOCATION_VIEW_BACKGROUND_OFFSET = "mapbox_locViewBackgroundOffset";
public static final String STATE_LOCATION_VIEW_BACKGROUND_TINT_COLOR = "mapbox_locViewBackgroundTintColor";
public static final String STATE_LOCATION_VIEW_ACCURACY_ALPHA = "mapbox_locViewAccuracyAlpha";
public static final String STATE_LOCATION_VIEW_ACCURACY_TINT_COLOR = "mapbox_locViewAccuracyTintColor";
public static final String STATE_LOCATION_VIEW_ACCURACY_THRESHOLD = "mapbox_locViewAccuracyThreshold";
public static final String STATE_LOCATION_VIEW_PADDING = "mapbox_locViewPadding";
public static final String STATE_DESELECT_MARKER_ON_TAP = "mapbox_deselectMarkerOnTap";
public static final String STATE_USER_FOCAL_POINT = "mapbox_userFocalPoint";
public static final String STATE_SCALE_ANIMATION_ENABLED = "mapbox_scaleAnimationEnabled";
public static final String STATE_ROTATE_ANIMATION_ENABLED = "mapbox_rotateAnimationEnabled";
public static final String STATE_FLING_ANIMATION_ENABLED = "mapbox_flingAnimationEnabled";
public static final String STATE_INCREASE_ROTATE_THRESHOLD = "mapbox_increaseRotateThreshold";
public static final String STATE_INCREASE_SCALE_THRESHOLD = "mapbox_increaseScaleThreshold";
}

View File

@@ -1,50 +0,0 @@
package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* MyBearingTracking exposes different types of bearing tracking modes.
* <p>
* These modes visualise the user direction by extracting the direction from either sensor or location data.
* </p>
* <p>
* Required to enable showing the user location first through {@link MapboxMap#setMyLocationEnabled(boolean)}.
* </p>
*
* @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyBearingTrackingMode(int)
* @see MyLocationView#setMyBearingTrackingMode(int)
*/
public class MyBearingTracking {
@IntDef( {NONE, COMPASS, GPS, GPS_NORTH_FACING})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Bearing tracking is disabled
*/
public static final int NONE = 0x00000000;
/**
* Tracking the bearing of the user based on sensor data
*/
public static final int COMPASS = 0x00000004;
/**
* Tracking the bearing of the user based on GPS data
*/
public static final int GPS = 0x00000008;
/**
* Tracking the bearing of the user based on GPS data, but camera always faces north direction
*/
public static final int GPS_NORTH_FACING = 0x0000000B;
}

View File

@@ -1,42 +0,0 @@
package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* MyLocationTracking exposes types of location tracking modes.
* * <p>
* This allows tracking the user location on screen by updating the camera position when a location update occurs.
* </p>
* <p>
* Required to enable showing the user location first through {@link MapboxMap#setMyLocationEnabled(boolean)}.
* </p>
*
* @see MapboxMap#setMyLocationEnabled(boolean)
* @see TrackingSettings#setMyLocationTrackingMode(int)
*/
public class MyLocationTracking {
@IntDef( {TRACKING_NONE, TRACKING_FOLLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Tracking the location of the user is disabled.
*/
public static final int TRACKING_NONE = 0x00000000;
/**
* Tracking the location of the user. {@link MapView} will reposition to center of {@link MyLocationView}
*/
public static final int TRACKING_FOLLOW = 0x00000004;
}

View File

@@ -67,7 +67,7 @@ public class LatLngBounds implements Parcelable {
double latCenter = (this.latitudeNorth + this.latitudeSouth) / 2.0;
double longCenter;
if (this.longitudeEast > this.longitudeWest) {
if (this.longitudeEast >= this.longitudeWest) {
longCenter = (this.longitudeEast + this.longitudeWest) / 2;
} else {
double halfSpan = (GeometryConstants.LONGITUDE_SPAN + this.longitudeEast - this.longitudeWest) / 2.0;
@@ -180,7 +180,7 @@ public class LatLngBounds implements Parcelable {
*/
public double getLongitudeSpan() {
double longSpan = Math.abs(this.longitudeEast - this.longitudeWest);
if (this.longitudeEast > this.longitudeWest) {
if (this.longitudeEast >= this.longitudeWest) {
return longSpan;
}
@@ -191,7 +191,7 @@ public class LatLngBounds implements Parcelable {
static double getLongitudeSpan(final double longEast, final double longWest) {
double longSpan = Math.abs(longEast - longWest);
if (longEast > longWest) {
if (longEast >= longWest) {
return longSpan;
}
@@ -283,6 +283,8 @@ public class LatLngBounds implements Parcelable {
* 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],
@@ -312,6 +314,10 @@ public class LatLngBounds implements Parcelable {
throw new IllegalArgumentException("latitude must be between -90 and 90");
}
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);
@@ -388,7 +394,7 @@ public class LatLngBounds implements Parcelable {
}
static boolean containsLongitude(final double eastLon, final double westLon, final double longitude) {
if (eastLon > westLon) {
if (eastLon >= westLon) {
return (longitude <= eastLon)
&& (longitude >= westLon);
}
@@ -438,10 +444,21 @@ public class LatLngBounds implements Parcelable {
* @return BoundingBox
*/
public LatLngBounds union(final double latNorth, final double lonEast, final double latSouth, final double lonWest) {
return new LatLngBounds((this.latitudeNorth < latNorth) ? latNorth : this.latitudeNorth,
(this.longitudeEast < lonEast) ? lonEast : this.longitudeEast,
(this.latitudeSouth > latSouth) ? latSouth : this.latitudeSouth,
(this.longitudeWest > lonWest) ? lonWest : this.longitudeWest);
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,
this.longitudeWest);
}
return new LatLngBounds(north,
this.longitudeEast,
south,
lonWest);
}
/**

View File

@@ -4,6 +4,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.constants.GeometryConstants;
/**
* A geographical span defined by its latitude and longitude span.
*/
@@ -136,4 +138,20 @@ public class LatLngSpan implements Parcelable {
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
/**
* Get the absolute distance, in degrees, between the west and
* east boundaries of this LatLngBounds
*
* @return Span distance
*/
static double getLongitudeSpan(double east, double west) {
double longSpan = Math.abs(east - west);
if (east > west) {
return longSpan;
}
// shortest span contains antimeridian
return GeometryConstants.LONGITUDE_SPAN - longSpan;
}
}

View File

@@ -3,8 +3,11 @@ package com.mapbox.mapboxsdk.http;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import com.mapbox.android.telemetry.TelemetryUtils;
import com.mapbox.mapboxsdk.BuildConfig;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
@@ -26,54 +29,41 @@ import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.Util;
import okhttp3.ResponseBody;
import timber.log.Timber;
import static android.util.Log.DEBUG;
import static android.util.Log.ERROR;
import static android.util.Log.INFO;
import static android.util.Log.VERBOSE;
import static android.util.Log.WARN;
class HTTPRequest implements Callback {
private static OkHttpClient mClient = new OkHttpClient.Builder().dispatcher(getDispatcher()).build();
private static boolean logEnabled = true;
private static boolean logRequestUrl = false;
private String USER_AGENT_STRING = null;
private static final int CONNECTION_ERROR = 0;
private static final int TEMPORARY_ERROR = 1;
private static final int PERMANENT_ERROR = 2;
// Reentrancy is not needed, but "Lock" is an
// abstract class.
private ReentrantLock mLock = new ReentrantLock();
private static OkHttpClient client = new OkHttpClient.Builder().dispatcher(getDispatcher()).build();
private static boolean logEnabled = true;
private static boolean logRequestUrl = false;
private long mNativePtr = 0;
private Call mCall;
private Request mRequest;
private static Dispatcher getDispatcher() {
Dispatcher dispatcher = new Dispatcher();
// Matches core limit set on
// https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/src/http_file_source.cpp#L192
dispatcher.setMaxRequestsPerHost(20);
return dispatcher;
}
private native void nativeOnFailure(int type, String message);
private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
String retryAfter, String xRateLimitReset, byte[] body);
// Reentrancy is not needed, but "Lock" is an abstract class.
private ReentrantLock lock = new ReentrantLock();
private String userAgentString;
private long nativePtr = 0;
private Call call;
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
mNativePtr = nativePtr;
this.nativePtr = nativePtr;
try {
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
if (httpUrl == null) {
log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
}
final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
// Don't try a request to remote server if we aren't connected
if (!Mapbox.isConnected() && !host.equals("127.0.0.1") && !host.equals("localhost")) {
throw new NoRouteToHostException("No Internet connection available.");
@@ -98,18 +88,18 @@ class HTTPRequest implements Callback {
} else if (modified.length() > 0) {
builder = builder.addHeader("If-Modified-Since", modified);
}
mRequest = builder.build();
mCall = mClient.newCall(mRequest);
mCall.enqueue(this);
Request request = builder.build();
call = client.newCall(request);
call.enqueue(this);
} catch (Exception exception) {
handleFailure(mCall, exception);
handleFailure(call, exception);
}
}
public void cancel() {
// mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
if (mCall != null) {
mCall.cancel();
// call can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
if (call != null) {
call.cancel();
}
// TODO: We need a lock here because we can try
@@ -117,37 +107,40 @@ class HTTPRequest implements Callback {
// answered on the OkHTTP thread. We could get rid of
// this lock by using Runnable when we move Android
// implementation of mbgl::RunLoop to Looper.
mLock.lock();
mNativePtr = 0;
mLock.unlock();
lock.lock();
nativePtr = 0;
lock.unlock();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if (response.isSuccessful()) {
log(VERBOSE, String.format("[HTTP] Request was successful (code = %s).", response.code()));
} else {
// We don't want to call this unsuccessful because a 304 isn't really an error
String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
log(DEBUG, String.format("[HTTP] Request with response code = %s: %s", response.code(), message));
}
if (logEnabled) {
if (response.isSuccessful()) {
Timber.v("[HTTP] Request was successful (code = %s).", response.code());
} else {
// We don't want to call this unsuccessful because a 304 isn't really an error
String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
Timber.d("[HTTP] Request with response code = %s: %s", response.code(), message);
}
ResponseBody responseBody = response.body();
if (responseBody == null) {
log(ERROR, "[HTTP] Received empty response body");
return;
}
byte[] body;
try {
body = response.body().bytes();
body = responseBody.bytes();
} catch (IOException ioException) {
onFailure(call, ioException);
// throw ioException;
return;
} finally {
response.body().close();
response.close();
}
mLock.lock();
if (mNativePtr != 0) {
lock.lock();
if (nativePtr != 0) {
nativeOnResponse(response.code(),
response.header("ETag"),
response.header("Last-Modified"),
@@ -157,14 +150,34 @@ class HTTPRequest implements Callback {
response.header("x-rate-limit-reset"),
body);
}
mLock.unlock();
lock.unlock();
}
@Override
public void onFailure(Call call, IOException e) {
public void onFailure(@NonNull Call call, @NonNull IOException e) {
handleFailure(call, e);
}
static void enableLog(boolean enabled) {
logEnabled = enabled;
}
static void enablePrintRequestUrlOnFailure(boolean enabled) {
logRequestUrl = enabled;
}
static void setOKHttpClient(OkHttpClient client) {
HTTPRequest.client = client;
}
private static Dispatcher getDispatcher() {
Dispatcher dispatcher = new Dispatcher();
// Matches core limit set on
// https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/src/http_file_source.cpp#L192
dispatcher.setMaxRequestsPerHost(20);
return dispatcher;
}
private void handleFailure(Call call, Exception e) {
String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
int type = getFailureType(e);
@@ -174,11 +187,11 @@ class HTTPRequest implements Callback {
logFailure(type, errorMessage, requestUrl);
}
mLock.lock();
if (mNativePtr != 0) {
lock.lock();
if (nativePtr != 0) {
nativeOnFailure(type, errorMessage);
}
mLock.unlock();
lock.unlock();
}
private int getFailureType(Exception e) {
@@ -191,19 +204,26 @@ class HTTPRequest implements Callback {
return PERMANENT_ERROR;
}
private void log(int type, String errorMessage) {
if (logEnabled) {
Timber.log(type, errorMessage);
}
}
private void logFailure(int type, String errorMessage, String requestUrl) {
Timber.log(
type == TEMPORARY_ERROR ? DEBUG : type == CONNECTION_ERROR ? INFO : WARN,
"Request failed due to a %s error: %s %s",
type == TEMPORARY_ERROR ? "temporary" : type == CONNECTION_ERROR ? "connection" : "permanent",
errorMessage,
logRequestUrl ? requestUrl : ""
log(type == TEMPORARY_ERROR ? DEBUG : type == CONNECTION_ERROR ? INFO : WARN,
String.format(
"Request failed due to a %s error: %s %s",
type == TEMPORARY_ERROR ? "temporary" : type == CONNECTION_ERROR ? "connection" : "permanent",
errorMessage,
logRequestUrl ? requestUrl : ""
)
);
}
private String getUserAgent() {
if (USER_AGENT_STRING == null) {
return USER_AGENT_STRING = Util.toHumanReadableAscii(
if (userAgentString == null) {
userAgentString = TelemetryUtils.toHumanReadableAscii(
String.format("%s %s (%s) Android/%s (%s)",
getApplicationIdentifier(),
BuildConfig.MAPBOX_VERSION_STRING,
@@ -211,9 +231,8 @@ class HTTPRequest implements Callback {
Build.VERSION.SDK_INT,
Build.CPU_ABI)
);
} else {
return USER_AGENT_STRING;
}
return userAgentString;
}
private String getApplicationIdentifier() {
@@ -226,15 +245,8 @@ class HTTPRequest implements Callback {
}
}
static void enableLog(boolean enabled) {
logEnabled = enabled;
}
private native void nativeOnFailure(int type, String message);
static void enablePrintRequestUrlOnFailure(boolean enabled) {
logRequestUrl = enabled;
}
static void setOKHttpClient(OkHttpClient client) {
mClient = client;
}
private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
String retryAfter, String xRateLimitReset, byte[] body);
}

View File

@@ -12,6 +12,7 @@ import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import com.mapbox.android.telemetry.TelemetryEnabler;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.attribution.Attribution;
import com.mapbox.mapboxsdk.attribution.AttributionParser;
@@ -98,7 +99,8 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt
builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Events.obtainTelemetry().enable();
TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.ENABLED);
Telemetry.obtainTelemetry().enable();
dialog.cancel();
}
});
@@ -112,7 +114,8 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt
builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Events.obtainTelemetry().disable();
Telemetry.obtainTelemetry().disable();
TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.DISABLED);
dialog.cancel();
}
});

View File

@@ -12,6 +12,7 @@ import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import com.mapbox.android.gestures.AndroidGesturesManager;
import com.mapbox.android.gestures.Constants;
import com.mapbox.android.gestures.MoveGestureDetector;
import com.mapbox.android.gestures.MultiFingerTapGestureDetector;
import com.mapbox.android.gestures.RotateGestureDetector;
@@ -105,8 +106,40 @@ final class MapGestureDetector {
// Checking for context != null for testing purposes
if (context != null) {
gesturesManager = new AndroidGesturesManager(context);
// Initialize gestures manager
AndroidGesturesManager androidGesturesManager = new AndroidGesturesManager(context);
initializeGesturesManager(androidGesturesManager, true);
// Initialize gesture listeners
initializeGestureListeners(context, true);
}
}
private void initializeGestureListeners(Context context, boolean attachDefaultListeners) {
if (attachDefaultListeners) {
StandardGestureListener standardGestureListener = new StandardGestureListener();
MoveGestureListener moveGestureListener = new MoveGestureListener();
ScaleGestureListener scaleGestureListener = new ScaleGestureListener(
context.getResources().getDimension(R.dimen.mapbox_minimum_scale_velocity));
RotateGestureListener rotateGestureListener = new RotateGestureListener(
context.getResources().getDimension(R.dimen.mapbox_minimum_scale_span_when_rotating),
context.getResources().getDimension(R.dimen.mapbox_minimum_angular_velocity),
context.getResources().getDimension(R.dimen.mapbox_defaultScaleSpanSinceStartThreshold));
ShoveGestureListener shoveGestureListener = new ShoveGestureListener();
TapGestureListener tapGestureListener = new TapGestureListener();
gesturesManager.setStandardGestureListener(standardGestureListener);
gesturesManager.setMoveGestureListener(moveGestureListener);
gesturesManager.setStandardScaleGestureListener(scaleGestureListener);
gesturesManager.setRotateGestureListener(rotateGestureListener);
gesturesManager.setShoveGestureListener(shoveGestureListener);
gesturesManager.setMultiFingerTapGestureListener(tapGestureListener);
}
}
private void initializeGesturesManager(AndroidGesturesManager androidGesturesManager,
boolean setDefaultMutuallyExclusives) {
if (setDefaultMutuallyExclusives) {
Set<Integer> shoveScaleSet = new HashSet<>();
shoveScaleSet.add(AndroidGesturesManager.GESTURE_TYPE_SHOVE);
shoveScaleSet.add(AndroidGesturesManager.GESTURE_TYPE_SCALE);
@@ -119,20 +152,10 @@ final class MapGestureDetector {
ScaleLongPressSet.add(AndroidGesturesManager.GESTURE_TYPE_SCALE);
ScaleLongPressSet.add(AndroidGesturesManager.GESTURE_TYPE_LONG_PRESS);
gesturesManager.setMutuallyExclusiveGestures(shoveScaleSet, shoveRotateSet, ScaleLongPressSet);
gesturesManager.setStandardGestureListener(new StandardGestureListener());
gesturesManager.setMoveGestureListener(new MoveGestureListener());
gesturesManager.setStandardScaleGestureListener(new ScaleGestureListener(
context.getResources().getDimension(R.dimen.mapbox_minimum_scale_velocity)
));
gesturesManager.setRotateGestureListener(new RotateGestureListener(
context.getResources().getDimension(R.dimen.mapbox_minimum_scale_span_when_rotating),
context.getResources().getDimension(R.dimen.mapbox_minimum_angular_velocity)
));
gesturesManager.setShoveGestureListener(new ShoveGestureListener());
gesturesManager.setMultiFingerTapGestureListener(new TapGestureListener());
androidGesturesManager.setMutuallyExclusiveGestures(shoveScaleSet, shoveRotateSet, ScaleLongPressSet);
}
gesturesManager = androidGesturesManager;
}
/**
@@ -218,15 +241,17 @@ final class MapGestureDetector {
}
void cancelAnimators() {
if (scaleAnimator != null) {
scaleAnimator.cancel();
}
if (rotateAnimator != null) {
rotateAnimator.cancel();
}
animationsTimeoutHandler.removeCallbacksAndMessages(null);
scheduledAnimators.clear();
cancelAnimator(scaleAnimator);
cancelAnimator(rotateAnimator);
}
private void cancelAnimator(Animator animator) {
if (animator != null && animator.isStarted()) {
animator.cancel();
}
}
/**
@@ -319,7 +344,7 @@ final class MapGestureDetector {
notifyOnMapClickListeners(tapPoint);
}
sendTelemetryEvent(Events.SINGLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
sendTelemetryEvent(Telemetry.SINGLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
return true;
}
@@ -338,16 +363,19 @@ final class MapGestureDetector {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
PointF zoomFocalPoint;
// Single finger double tap
if (focalPoint != null) {
// User provided focal point
transform.zoomIn(focalPoint);
zoomFocalPoint = focalPoint;
} else {
// Zoom in on gesture
transform.zoomIn(new PointF(motionEvent.getX(), motionEvent.getY()));
zoomFocalPoint = new PointF(motionEvent.getX(), motionEvent.getY());
}
sendTelemetryEvent(Events.DOUBLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
zoomInAnimated(zoomFocalPoint, false);
sendTelemetryEvent(Telemetry.DOUBLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
return true;
}
@@ -362,8 +390,14 @@ final class MapGestureDetector {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if ((!uiSettings.isScrollGesturesEnabled())) {
// don't allow a fling is scroll is disabled
if (!uiSettings.isScrollGesturesEnabled()) {
// don't allow a fling if scroll is disabled
return false;
}
notifyOnFlingListeners();
if (!uiSettings.isFlingVelocityAnimationEnabled()) {
return false;
}
@@ -391,8 +425,6 @@ final class MapGestureDetector {
// update transformation
transform.moveBy(offsetX, offsetY, animationTime);
notifyOnFlingListeners();
return true;
}
}
@@ -407,7 +439,7 @@ final class MapGestureDetector {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
sendTelemetryEvent(Events.PAN, detector.getFocalPoint());
sendTelemetryEvent(Telemetry.PAN, detector.getFocalPoint());
notifyOnMoveBeginListeners(detector);
@@ -461,16 +493,18 @@ final class MapGestureDetector {
gesturesManager.getMoveGestureDetector().setEnabled(false);
}
// increase rotate angle threshold when scale is detected first
gesturesManager.getRotateGestureDetector().setAngleThreshold(
gesturesManager.getRotateGestureDetector().getDefaultAngleThreshold()
+ MapboxConstants.ROTATION_THRESHOLD_INCREASE_WHEN_SCALING
);
if (uiSettings.isIncreaseRotateThresholdWhenScaling()) {
// increase rotate angle threshold when scale is detected first
gesturesManager.getRotateGestureDetector().setAngleThreshold(
Constants.DEFAULT_ROTATE_ANGLE_THRESHOLD
+ MapboxConstants.ROTATION_THRESHOLD_INCREASE_WHEN_SCALING
);
}
// setting focalPoint in #onScaleBegin() as well, because #onScale() might not get called before #onScaleEnd()
setScaleFocalPoint(detector);
sendTelemetryEvent(Events.PINCH, scaleFocalPoint);
sendTelemetryEvent(Telemetry.PINCH, scaleFocalPoint);
notifyOnScaleBeginListeners(detector);
@@ -502,21 +536,27 @@ final class MapGestureDetector {
gesturesManager.getMoveGestureDetector().setEnabled(true);
}
// resetting default angle threshold
gesturesManager.getRotateGestureDetector().setAngleThreshold(
gesturesManager.getRotateGestureDetector().getDefaultAngleThreshold()
);
if (uiSettings.isIncreaseRotateThresholdWhenScaling()) {
// resetting default angle threshold
gesturesManager.getRotateGestureDetector().setAngleThreshold(
Constants.DEFAULT_ROTATE_ANGLE_THRESHOLD
);
}
notifyOnScaleEndListeners(detector);
if (!uiSettings.isScaleVelocityAnimationEnabled()) {
return;
}
float velocityXY = Math.abs(velocityX) + Math.abs(velocityY);
if (velocityXY > minimumVelocity) {
double zoomAddition = calculateScale(velocityXY, detector.isScalingOut());
double currentZoom = transform.getRawZoom();
long animationTime = (long) (Math.abs(zoomAddition) * 1000 / 4);
scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, animationTime);
scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, scaleFocalPoint, animationTime);
scheduleAnimator(scaleAnimator);
}
notifyOnScaleEndListeners(detector);
}
private void setScaleFocalPoint(StandardScaleGestureDetector detector) {
@@ -540,39 +580,6 @@ final class MapGestureDetector {
return zoomAddition;
}
private Animator createScaleAnimator(double currentZoom, double zoomAddition, long animationTime) {
ValueAnimator animator = ValueAnimator.ofFloat((float) currentZoom, (float) (currentZoom + zoomAddition));
animator.setDuration(animationTime);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
transform.setZoom((Float) animation.getAnimatedValue(), scaleFocalPoint, 0);
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
}
@Override
public void onAnimationCancel(Animator animation) {
transform.cancelTransitions();
}
@Override
public void onAnimationEnd(Animator animation) {
cameraChangeDispatcher.onCameraIdle();
}
});
return animator;
}
private double getNewZoom(float scaleFactor, boolean quickZoom) {
double zoomBy = Math.log(scaleFactor) / Math.log(Math.PI / 2);
if (quickZoom) {
@@ -591,10 +598,13 @@ final class MapGestureDetector {
private PointF rotateFocalPoint;
private final float minimumScaleSpanWhenRotating;
private final float minimumAngularVelocity;
private final float defaultSpanSinceStartThreshold;
RotateGestureListener(float minimumScaleSpanWhenRotating, float minimumAngularVelocity) {
public RotateGestureListener(float minimumScaleSpanWhenRotating, float minimumAngularVelocity,
float defaultSpanSinceStartThreshold) {
this.minimumScaleSpanWhenRotating = minimumScaleSpanWhenRotating;
this.minimumAngularVelocity = minimumAngularVelocity;
this.defaultSpanSinceStartThreshold = defaultSpanSinceStartThreshold;
}
@Override
@@ -606,15 +616,17 @@ final class MapGestureDetector {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
// when rotation starts, interrupting scale and increasing the threshold
// to make rotation without scaling easier
gesturesManager.getStandardScaleGestureDetector().setSpanSinceStartThreshold(minimumScaleSpanWhenRotating);
gesturesManager.getStandardScaleGestureDetector().interrupt();
if (uiSettings.isIncreaseScaleThresholdWhenRotating()) {
// when rotation starts, interrupting scale and increasing the threshold
// to make rotation without scaling easier
gesturesManager.getStandardScaleGestureDetector().setSpanSinceStartThreshold(minimumScaleSpanWhenRotating);
gesturesManager.getStandardScaleGestureDetector().interrupt();
}
// setting in #onRotateBegin() as well, because #onRotate() might not get called before #onRotateEnd()
setRotateFocalPoint(detector);
sendTelemetryEvent(Events.ROTATION, rotateFocalPoint);
sendTelemetryEvent(Telemetry.ROTATION, rotateFocalPoint);
notifyOnRotateBeginListeners(detector);
@@ -644,9 +656,16 @@ final class MapGestureDetector {
public void onRotateEnd(RotateGestureDetector detector, float velocityX, float velocityY, float angularVelocity) {
cameraChangeDispatcher.onCameraIdle();
// resetting default scale threshold values
gesturesManager.getStandardScaleGestureDetector().setSpanSinceStartThreshold(
gesturesManager.getStandardScaleGestureDetector().getDefaultSpanSinceStartThreshold());
if (uiSettings.isIncreaseScaleThresholdWhenRotating()) {
// resetting default scale threshold values
gesturesManager.getStandardScaleGestureDetector().setSpanSinceStartThreshold(defaultSpanSinceStartThreshold);
}
notifyOnRotateEndListeners(detector);
if (!uiSettings.isRotateVelocityAnimationEnabled()) {
return;
}
if (Math.abs(angularVelocity) < minimumAngularVelocity) {
return;
@@ -665,8 +684,6 @@ final class MapGestureDetector {
rotateAnimator = createRotateAnimator(angularVelocity, animationTime);
scheduleAnimator(rotateAnimator);
notifyOnRotateEndListeners(detector);
}
private void setRotateFocalPoint(RotateGestureDetector detector) {
@@ -727,7 +744,7 @@ final class MapGestureDetector {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
sendTelemetryEvent(Events.PITCH, detector.getFocalPoint());
sendTelemetryEvent(Telemetry.PITCH, detector.getFocalPoint());
// disabling move gesture during shove
gesturesManager.getMoveGestureDetector().setEnabled(false);
@@ -776,23 +793,104 @@ final class MapGestureDetector {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
sendTelemetryEvent(Telemetry.TWO_FINGER_TAP, detector.getFocalPoint());
PointF zoomFocalPoint;
// Single finger double tap
if (focalPoint != null) {
transform.zoomOut(focalPoint);
// User provided focal point
zoomFocalPoint = focalPoint;
} else {
transform.zoomOut(detector.getFocalPoint());
// Zoom in on gesture
zoomFocalPoint = detector.getFocalPoint();
}
zoomOutAnimated(zoomFocalPoint, false);
return true;
}
}
private Animator createScaleAnimator(double currentZoom, double zoomAddition, final PointF animationFocalPoint,
long animationTime) {
ValueAnimator animator = ValueAnimator.ofFloat((float) currentZoom, (float) (currentZoom + zoomAddition));
animator.setDuration(animationTime);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
transform.setZoom((Float) animation.getAnimatedValue(), animationFocalPoint);
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
}
@Override
public void onAnimationCancel(Animator animation) {
transform.cancelTransitions();
}
@Override
public void onAnimationEnd(Animator animation) {
cameraChangeDispatcher.onCameraIdle();
}
});
return animator;
}
/**
* Zoom in by 1.
*
* @param zoomFocalPoint focal point of zoom animation
* @param runImmediately if true, animation will be started right away, otherwise it will wait until
* {@link MotionEvent#ACTION_UP} is registered.
*/
void zoomInAnimated(PointF zoomFocalPoint, boolean runImmediately) {
zoomAnimated(true, zoomFocalPoint, runImmediately);
}
/**
* Zoom out by 1.
*
* @param zoomFocalPoint focal point of zoom animation
* @param runImmediately if true, animation will be started right away, otherwise it will wait until
* {@link MotionEvent#ACTION_UP} is registered.
*/
void zoomOutAnimated(PointF zoomFocalPoint, boolean runImmediately) {
zoomAnimated(false, zoomFocalPoint, runImmediately);
}
private void zoomAnimated(boolean zoomIn, PointF zoomFocalPoint, boolean runImmediately) {
//canceling here as well, because when using a button it will not be canceled automatically by onDown()
cancelAnimator(scaleAnimator);
double currentZoom = transform.getRawZoom();
scaleAnimator = createScaleAnimator(
currentZoom,
zoomIn ? 1 : -1,
zoomFocalPoint,
MapboxConstants.ANIMATION_DURATION);
if (runImmediately) {
scaleAnimator.start();
} else {
scheduleAnimator(scaleAnimator);
}
}
private void sendTelemetryEvent(String eventType, PointF focalPoint) {
if (isZoomValid(transform)) {
MapEventFactory mapEventFactory = new MapEventFactory();
LatLng latLng = projection.fromScreenLocation(focalPoint);
MapState state = new MapState(latLng.getLatitude(), latLng.getLongitude(), transform.getZoom());
state.setGesture(eventType);
Events.obtainTelemetry().push(mapEventFactory.createMapGestureEvent(Event.Type.MAP_CLICK, state));
Telemetry.obtainTelemetry().push(mapEventFactory.createMapGestureEvent(Event.Type.MAP_CLICK, state));
}
}
@@ -1008,7 +1106,9 @@ final class MapGestureDetector {
return gesturesManager;
}
void setGesturesManager(AndroidGesturesManager gesturesManager) {
this.gesturesManager = gesturesManager;
void setGesturesManager(Context context, AndroidGesturesManager gesturesManager, boolean attachDefaultListeners,
boolean setDefaultMutuallyExclusives) {
initializeGesturesManager(gesturesManager, setDefaultMutuallyExclusives);
initializeGestureListeners(context, attachDefaultListeners);
}
}

View File

@@ -13,24 +13,22 @@ import android.view.ViewConfiguration;
* <p>
* <ul>
* <li> Uses {@link Transform} to change the map state</li>
* <li> Uses {@link TrackingSettings} to verify validity of the current tracking mode.</li>
* <li> Uses {@link UiSettings} to verify validity of user restricted movement.</li>
* </ul>
* <p>
*/
final class MapKeyListener {
private final TrackingSettings trackingSettings;
private final Transform transform;
private final UiSettings uiSettings;
private final MapGestureDetector mapGestureDetector;
private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
MapKeyListener(@NonNull Transform transform, @NonNull TrackingSettings trackingSettings,
@NonNull UiSettings uiSettings) {
MapKeyListener(Transform transform, UiSettings uiSettings, MapGestureDetector mapGestureDetector) {
this.transform = transform;
this.trackingSettings = trackingSettings;
this.uiSettings = uiSettings;
this.mapGestureDetector = mapGestureDetector;
}
/**
@@ -55,7 +53,7 @@ final class MapKeyListener {
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
if (!uiSettings.isScrollGesturesEnabled()) {
return false;
}
@@ -67,7 +65,7 @@ final class MapKeyListener {
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
if (!uiSettings.isScrollGesturesEnabled()) {
return false;
}
@@ -79,7 +77,7 @@ final class MapKeyListener {
return true;
case KeyEvent.KEYCODE_DPAD_UP:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
if (!uiSettings.isScrollGesturesEnabled()) {
return false;
}
@@ -91,7 +89,7 @@ final class MapKeyListener {
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
if (!uiSettings.isScrollGesturesEnabled()) {
return false;
}
@@ -128,7 +126,7 @@ final class MapKeyListener {
// Zoom out
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
transform.zoomOut(focalPoint);
mapGestureDetector.zoomOutAnimated(focalPoint, true);
return true;
default:
@@ -164,7 +162,7 @@ final class MapKeyListener {
// Zoom in
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
transform.zoomIn(focalPoint);
mapGestureDetector.zoomInAnimated(focalPoint, true);
return true;
}
@@ -183,7 +181,7 @@ final class MapKeyListener {
switch (event.getActionMasked()) {
// The trackball was rotated
case MotionEvent.ACTION_MOVE:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
if (!uiSettings.isScrollGesturesEnabled()) {
return false;
}
@@ -219,7 +217,7 @@ final class MapKeyListener {
if (currentTrackballLongPressTimeOut != null) {
// Zoom in
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
transform.zoomIn(focalPoint);
mapGestureDetector.zoomInAnimated(focalPoint, true);
}
return true;
@@ -261,7 +259,7 @@ final class MapKeyListener {
if (!cancelled) {
// Zoom out
PointF pointF = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
transform.zoomOut(pointF);
mapGestureDetector.zoomOutAnimated(pointF, true);
// Ensure the up action is not run
currentTrackballLongPressTimeOut = null;

View File

@@ -38,8 +38,6 @@ import com.mapbox.mapboxsdk.maps.renderer.MapRenderer;
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.maps.widgets.MyLocationView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
import com.mapbox.mapboxsdk.storage.FileSource;
@@ -83,7 +81,6 @@ public class MapView extends FrameLayout {
private boolean destroyed;
private boolean hasSurface;
private MyLocationView myLocationView;
private CompassView compassView;
private PointF focalPoint;
private ImageView attrView;
@@ -131,7 +128,6 @@ public class MapView extends FrameLayout {
// inflate view
View view = LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_internal, this);
compassView = (CompassView) view.findViewById(R.id.compassView);
myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
attrView = (ImageView) view.findViewById(R.id.attributionView);
logoView = (ImageView) view.findViewById(R.id.logoView);
@@ -153,19 +149,12 @@ public class MapView extends FrameLayout {
// callback for registering touch listeners
GesturesManagerInteractionListener registerTouchListener = new GesturesManagerInteractionListener();
// callback for zooming in the camera
CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator();
// callback for camera change events
final CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher();
// setup components for MapboxMap creation
Projection proj = new Projection(nativeMapView);
UiSettings uiSettings = new UiSettings(proj, focalPointInvalidator, compassView, attrView, logoView);
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointInvalidator,
zoomInvalidator);
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj,
focalPointInvalidator);
LongSparseArray<Annotation> annotationsArray = new LongSparseArray<>();
MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
IconManager iconManager = new IconManager(nativeMapView);
@@ -176,30 +165,28 @@ public class MapView extends FrameLayout {
ShapeAnnotations shapeAnnotations = new ShapeAnnotationContainer(nativeMapView, annotationsArray);
AnnotationManager annotationManager = new AnnotationManager(nativeMapView, this, annotationsArray,
markerViewManager, iconManager, annotations, markers, polygons, polylines, shapeAnnotations);
Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(), trackingSettings,
Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(),
cameraChangeDispatcher);
mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj,
registerTouchListener, annotationManager, cameraChangeDispatcher);
focalPointInvalidator.addListener(mapboxMap.createFocalPointChangeListener());
mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, proj, registerTouchListener,
annotationManager, cameraChangeDispatcher);
mapCallback.attachMapboxMap(mapboxMap);
// user input
mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings,
annotationManager, cameraChangeDispatcher);
mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings);
mapKeyListener = new MapKeyListener(transform, uiSettings, mapGestureDetector);
// overlain zoom buttons
mapZoomButtonController = new MapZoomButtonController(new ZoomButtonsController(this));
MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform,
cameraChangeDispatcher, getWidth(), getHeight());
MapZoomControllerListener zoomListener = new MapZoomControllerListener(
mapGestureDetector, cameraChangeDispatcher, getWidth(), getHeight());
mapZoomButtonController.bind(uiSettings, zoomListener);
compassView.injectCompassAnimationListener(createCompassAnimationListener(cameraChangeDispatcher));
compassView.setOnClickListener(createCompassClickListener(cameraChangeDispatcher));
// inject widgets with MapboxMap
myLocationView.setMapboxMap(mapboxMap);
attrView.setOnClickListener(new AttributionClickListener(context, mapboxMap));
// Ensure this view is interactable
@@ -281,7 +268,7 @@ public class MapView extends FrameLayout {
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
MapboxTelemetry telemetry = Events.obtainTelemetry();
MapboxTelemetry telemetry = Telemetry.obtainTelemetry();
AppUserTurnstile turnstileEvent = new AppUserTurnstile(BuildConfig.MAPBOX_SDK_IDENTIFIER,
BuildConfig.MAPBOX_SDK_VERSION);
telemetry.push(turnstileEvent);
@@ -295,7 +282,9 @@ public class MapView extends FrameLayout {
private void initialiseDrawingSurface(MapboxMapOptions options) {
if (options.getTextureMode()) {
TextureView textureView = new TextureView(getContext());
mapRenderer = new TextureViewMapRenderer(getContext(), textureView, options.getLocalIdeographFontFamily()) {
String localFontFamily = options.getLocalIdeographFontFamily();
boolean translucentSurface = options.getTranslucentTextureSurface();
mapRenderer = new TextureViewMapRenderer(getContext(), textureView, localFontFamily, translucentSurface) {
@Override
protected void onSurfaceCreated(GL10 gl, EGLConfig config) {
MapView.this.onSurfaceCreated();
@@ -324,11 +313,14 @@ public class MapView extends FrameLayout {
private void onSurfaceCreated() {
hasSurface = true;
post(() -> {
// Initialise only when not destroyed and only once
if (!destroyed && mapboxMap == null) {
initialiseMap();
mapboxMap.onStart();
post(new Runnable() {
@Override
public void run() {
// Initialise only when not destroyed and only once
if (!destroyed && mapboxMap == null) {
MapView.this.initialiseMap();
mapboxMap.onStart();
}
}
});
}
@@ -1032,25 +1024,28 @@ public class MapView extends FrameLayout {
}
@Override
public void setGesturesManager(AndroidGesturesManager gesturesManager) {
mapGestureDetector.setGesturesManager(gesturesManager);
public void setGesturesManager(AndroidGesturesManager gesturesManager, boolean attachDefaultListeners,
boolean setDefaultMutuallyExclusives) {
mapGestureDetector.setGesturesManager(
getContext(), gesturesManager, attachDefaultListeners, setDefaultMutuallyExclusives);
}
@Override
public void cancelAllVelocityAnimations() {
mapGestureDetector.cancelAnimators();
}
}
private static class MapZoomControllerListener implements ZoomButtonsController.OnZoomListener {
private final MapGestureDetector mapGestureDetector;
private final UiSettings uiSettings;
private final Transform transform;
private final CameraChangeDispatcher cameraChangeDispatcher;
private final float mapWidth;
private final float mapHeight;
MapZoomControllerListener(MapGestureDetector detector, UiSettings uiSettings, Transform transform,
CameraChangeDispatcher dispatcher, float mapWidth, float mapHeight) {
MapZoomControllerListener(MapGestureDetector detector, CameraChangeDispatcher dispatcher,
float mapWidth, float mapHeight) {
this.mapGestureDetector = detector;
this.uiSettings = uiSettings;
this.transform = transform;
this.cameraChangeDispatcher = dispatcher;
this.mapWidth = mapWidth;
this.mapHeight = mapHeight;
@@ -1074,30 +1069,9 @@ public class MapView extends FrameLayout {
focalPoint = new PointF(mapWidth / 2, mapHeight / 2);
}
if (zoomIn) {
transform.zoomIn(focalPoint);
mapGestureDetector.zoomInAnimated(focalPoint, true);
} else {
transform.zoomOut(focalPoint);
}
}
}
private class CameraZoomInvalidator implements TrackingSettings.CameraZoomInvalidator {
@Override
public void zoomTo(double zoomLevel) {
Transform transform = mapboxMap.getTransform();
double currentZoomLevel = transform.getCameraPosition().zoom;
if (currentZoomLevel < zoomLevel) {
setZoom(zoomLevel, mapGestureDetector.getFocalPoint(), transform);
}
}
private void setZoom(double zoomLevel, @Nullable PointF focalPoint, @NonNull Transform transform) {
if (focalPoint != null) {
transform.setZoom(zoomLevel, focalPoint);
} else {
PointF centerPoint = new PointF(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
transform.setZoom(zoomLevel, centerPoint);
mapGestureDetector.zoomOutAnimated(focalPoint, true);
}
}
}

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.RectF;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.FloatRange;
import android.support.annotation.IntRange;
@@ -16,7 +15,6 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import com.mapbox.android.core.location.LocationEngine;
import com.mapbox.android.gestures.AndroidGesturesManager;
import com.mapbox.android.gestures.MoveGestureDetector;
import com.mapbox.android.gestures.RotateGestureDetector;
@@ -39,13 +37,10 @@ import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdate;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.style.layers.Filter;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.light.Light;
import com.mapbox.mapboxsdk.style.sources.Source;
@@ -71,26 +66,21 @@ public final class MapboxMap {
private final NativeMapView nativeMapView;
private final UiSettings uiSettings;
private final TrackingSettings trackingSettings;
private final Projection projection;
private final Transform transform;
private final AnnotationManager annotationManager;
private final MyLocationViewSettings myLocationViewSettings;
private final CameraChangeDispatcher cameraChangeDispatcher;
private final OnGesturesManagerInteractionListener onGesturesManagerInteractionListener;
private MapboxMap.OnFpsChangedListener onFpsChangedListener;
private PointF focalPoint;
MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking,
MyLocationViewSettings myLocationView, Projection projection, OnGesturesManagerInteractionListener listener,
AnnotationManager annotations, CameraChangeDispatcher cameraChangeDispatcher) {
MapboxMap(NativeMapView map, Transform transform, UiSettings ui, Projection projection,
OnGesturesManagerInteractionListener listener, AnnotationManager annotations,
CameraChangeDispatcher cameraChangeDispatcher) {
this.nativeMapView = map;
this.uiSettings = ui;
this.trackingSettings = tracking;
this.projection = projection;
this.myLocationViewSettings = myLocationView;
this.annotationManager = annotations.bind(this);
this.transform = transform;
this.onGesturesManagerInteractionListener = listener;
@@ -100,8 +90,6 @@ public final class MapboxMap {
void initialise(@NonNull Context context, @NonNull MapboxMapOptions options) {
transform.initialise(this, options);
uiSettings.initialise(context, options);
myLocationViewSettings.initialise(options);
trackingSettings.initialise(options);
// Map configuration
setDebugActive(options.getDebugActive());
@@ -115,8 +103,7 @@ public final class MapboxMap {
*/
void onStart() {
nativeMapView.update();
trackingSettings.onStart();
if (TextUtils.isEmpty(nativeMapView.getStyleUrl())) {
if (TextUtils.isEmpty(nativeMapView.getStyleUrl()) && TextUtils.isEmpty(nativeMapView.getStyleJson())) {
// if user hasn't loaded a Style yet
nativeMapView.setStyleUrl(Style.MAPBOX_STREETS);
}
@@ -126,7 +113,6 @@ public final class MapboxMap {
* Called when the hosting Activity/Fragment onStop() method is called.
*/
void onStop() {
trackingSettings.onStop();
}
/**
@@ -138,9 +124,7 @@ public final class MapboxMap {
outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, transform.getCameraPosition());
outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, nativeMapView.getDebug());
outState.putString(MapboxConstants.STATE_STYLE_URL, nativeMapView.getStyleUrl());
trackingSettings.onSaveInstanceState(outState);
uiSettings.onSaveInstanceState(outState);
myLocationViewSettings.onSaveInstanceState(outState);
}
/**
@@ -151,9 +135,7 @@ public final class MapboxMap {
void onRestoreInstanceState(Bundle savedInstanceState) {
final CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION);
myLocationViewSettings.onRestoreInstanceState(savedInstanceState);
uiSettings.onRestoreInstanceState(savedInstanceState);
trackingSettings.onRestoreInstanceState(savedInstanceState);
if (cameraPosition != null) {
moveCamera(CameraUpdateFactory.newCameraPosition(
@@ -173,6 +155,7 @@ public final class MapboxMap {
* Called before the OnMapReadyCallback is invoked.
*/
void onPreMapReady() {
invalidateCameraPosition();
annotationManager.reloadMarkers();
annotationManager.adjustTopOffsetPixels(this);
}
@@ -192,7 +175,6 @@ public final class MapboxMap {
* Called when the region is changing or has changed.
*/
void onUpdateRegionChange() {
trackingSettings.update();
annotationManager.update();
}
@@ -559,38 +541,6 @@ public final class MapboxMap {
return uiSettings;
}
//
// TrackingSettings
//
/**
* Gets the tracking interface settings for the map.
*
* @return the TrackingSettings asssociated with this map
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public TrackingSettings getTrackingSettings() {
return trackingSettings;
}
//
// MyLocationViewSettings
//
/**
* Gets the settings of the user location for the map.
*
* @return the MyLocationViewSettings associated with this map
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public MyLocationViewSettings getMyLocationViewSettings() {
return myLocationViewSettings;
}
//
// Projection
//
@@ -606,7 +556,7 @@ public final class MapboxMap {
}
//
//
// Light
//
/**
@@ -623,47 +573,6 @@ public final class MapboxMap {
// Camera API
//
/**
* Moves the center of the screen to a latitude and longitude specified by a LatLng object. This centers the
* camera on the LatLng object.
*
* @param latLng Target location to change to
*/
public void setLatLng(@NonNull LatLng latLng) {
nativeMapView.setLatLng(latLng);
}
/**
* Moves the camera viewpoint to a particular zoom level.
*
* @param zoom Zoom level to change to
*/
public void setZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double zoom) {
if (focalPoint == null) {
focalPoint = new PointF(nativeMapView.getWidth() / 2, nativeMapView.getHeight() / 2);
}
nativeMapView.setZoom(zoom, focalPoint, 0);
}
/**
* Moves the camera viewpoint angle to a particular angle in degrees.
*
* @param tilt Tilt angle to change to
*/
public void setTilt(@FloatRange(from = MapboxConstants.MINIMUM_TILT, to = MapboxConstants.MAXIMUM_TILT) double tilt) {
nativeMapView.setPitch(tilt, 0);
}
/**
* Moves the camera viewpoint direction to a particular angle in degrees.
*
* @param bearing Direction angle to change to
*/
public void setBearing(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION)
double bearing) {
nativeMapView.setBearing(bearing);
}
/**
* Cancels ongoing animations.
* <p>
@@ -791,11 +700,6 @@ public final class MapboxMap {
* unless specified within {@link CameraUpdate}. A callback can be used to be notified when
* easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
* will return the current location of the camera in flight.
* <p>
* Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling
* {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setDismissLocationTrackingOnGesture(boolean)} with false before
* invoking this method and calling it with true in the {@link CancelableCallback#onFinish()}.
* </p>
*
* @param update The change that should be applied to the camera.
* @param durationMs The duration of the animation in milliseconds. This must be strictly
@@ -817,11 +721,6 @@ public final class MapboxMap {
* unless specified within {@link CameraUpdate}. A callback can be used to be notified when
* easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
* will return the current location of the camera in flight.
* <p>
* Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling
* {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setDismissLocationTrackingOnGesture(boolean)} with false before
* invoking this method and calling it with true in the {@link CancelableCallback#onFinish()}.
* </p>
*
* @param update The change that should be applied to the camera.
* @param durationMs The duration of the animation in milliseconds. This must be strictly
@@ -917,7 +816,7 @@ public final class MapboxMap {
/**
* Invalidates the current camera position by reconstructing it from mbgl
*/
void invalidateCameraPosition() {
private void invalidateCameraPosition() {
CameraPosition cameraPosition = transform.invalidateCameraPosition();
if (cameraPosition != null) {
transform.updateCameraPosition(cameraPosition);
@@ -1652,19 +1551,8 @@ public final class MapboxMap {
* @return the camera position that fits the bounds and padding
*/
public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBounds, int[] padding) {
// calculate and set additional bounds padding
int[] mapPadding = getPadding();
for (int i = 0; i < padding.length; i++) {
padding[i] = mapPadding[i] + padding[i];
}
projection.setContentPadding(padding, myLocationViewSettings.getPadding());
// get padded camera position from LatLngBounds
CameraPosition cameraPosition = nativeMapView.getCameraForLatLngBounds(latLngBounds);
// reset map padding
setPadding(mapPadding);
return cameraPosition;
return nativeMapView.getCameraForLatLngBounds(latLngBounds, padding);
}
/**
@@ -1676,19 +1564,8 @@ public final class MapboxMap {
* @return the camera position that fits the bounds and padding
*/
public CameraPosition getCameraForGeometry(Geometry geometry, double bearing, int[] padding) {
// calculate and set additional bounds padding
int[] mapPadding = getPadding();
for (int i = 0; i < padding.length; i++) {
padding[i] = mapPadding[i] + padding[i];
}
projection.setContentPadding(padding, myLocationViewSettings.getPadding());
// get padded camera position from LatLngBounds
CameraPosition cameraPosition = nativeMapView.getCameraForGeometry(geometry, bearing);
// reset map padding
setPadding(mapPadding);
return cameraPosition;
// get padded camera position from Geometry
return nativeMapView.getCameraForGeometry(geometry, bearing, padding);
}
//
@@ -1697,13 +1574,13 @@ public final class MapboxMap {
/**
* <p>
* Sets the distance from the edges of the map view’s frame to the edges of the map
* view’s logical viewport.
* Sets the distance from the edges of the map view&#x27;s frame to the edges of the map
* view&#x27s logical viewport.
* </p>
* <p>
* When the value of this property is equal to {0,0,0,0}, viewport
* properties such as `centerCoordinate` assume a viewport that matches the map
* view’s frame. Otherwise, those properties are inset, excluding part of the
* properties such as &#x27;centerCoordinate&#x27; assume a viewport that matches the map
* view&#x27;s frame. Otherwise, those properties are inset, excluding part of the
* frame from the viewport. For instance, if the only the top edge is inset, the
* map center is effectively shifted downward.
* </p>
@@ -1718,7 +1595,7 @@ public final class MapboxMap {
}
private void setPadding(int[] padding) {
projection.setContentPadding(padding, myLocationViewSettings.getPadding());
projection.setContentPadding(padding);
uiSettings.invalidate();
}
@@ -1763,7 +1640,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
public void addOnCameraIdleListener(@Nullable OnCameraIdleListener listener) {
public void addOnCameraIdleListener(@NonNull OnCameraIdleListener listener) {
cameraChangeDispatcher.addOnCameraIdleListener(listener);
}
@@ -1772,7 +1649,7 @@ public final class MapboxMap {
*
* @param listener the listener to remove
*/
public void removeOnCameraIdleListener(@Nullable OnCameraIdleListener listener) {
public void removeOnCameraIdleListener(@NonNull OnCameraIdleListener listener) {
cameraChangeDispatcher.removeOnCameraIdleListener(listener);
}
@@ -1793,7 +1670,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
public void addOnCameraMoveCancelListener(@Nullable OnCameraMoveCanceledListener listener) {
public void addOnCameraMoveCancelListener(@NonNull OnCameraMoveCanceledListener listener) {
cameraChangeDispatcher.addOnCameraMoveCancelListener(listener);
}
@@ -1802,7 +1679,7 @@ public final class MapboxMap {
*
* @param listener the listener to remove
*/
public void removeOnCameraMoveCancelListener(@Nullable OnCameraMoveCanceledListener listener) {
public void removeOnCameraMoveCancelListener(@NonNull OnCameraMoveCanceledListener listener) {
cameraChangeDispatcher.removeOnCameraMoveCancelListener(listener);
}
@@ -1823,7 +1700,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
public void addOnCameraMoveStartedListener(@Nullable OnCameraMoveStartedListener listener) {
public void addOnCameraMoveStartedListener(@NonNull OnCameraMoveStartedListener listener) {
cameraChangeDispatcher.addOnCameraMoveStartedListener(listener);
}
@@ -1832,7 +1709,7 @@ public final class MapboxMap {
*
* @param listener the listener to remove
*/
public void removeOnCameraMoveStartedListener(@Nullable OnCameraMoveStartedListener listener) {
public void removeOnCameraMoveStartedListener(@NonNull OnCameraMoveStartedListener listener) {
cameraChangeDispatcher.removeOnCameraMoveStartedListener(listener);
}
@@ -1853,7 +1730,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
public void addOnCameraMoveListener(@Nullable OnCameraMoveListener listener) {
public void addOnCameraMoveListener(@NonNull OnCameraMoveListener listener) {
cameraChangeDispatcher.addOnCameraMoveListener(listener);
}
@@ -1862,7 +1739,7 @@ public final class MapboxMap {
*
* @param listener the listener to remove
*/
public void removeOnCameraMoveListener(@Nullable OnCameraMoveListener listener) {
public void removeOnCameraMoveListener(@NonNull OnCameraMoveListener listener) {
cameraChangeDispatcher.removeOnCameraMoveListener(listener);
}
@@ -1898,9 +1775,8 @@ public final class MapboxMap {
* Adds a callback that's invoked when the map is scrolled.
*
* @param listener The callback that's invoked when the map is scrolled.
* To unset the callback, use null.
*/
public void addOnScrollListener(@Nullable OnScrollListener listener) {
public void addOnScrollListener(@NonNull OnScrollListener listener) {
onGesturesManagerInteractionListener.onAddScrollListener(listener);
}
@@ -1908,9 +1784,8 @@ public final class MapboxMap {
* Removes a callback that's invoked when the map is scrolled.
*
* @param listener The callback that's invoked when the map is scrolled.
* To unset the callback, use null.
*/
public void removeOnScrollListener(@Nullable OnScrollListener listener) {
public void removeOnScrollListener(@NonNull OnScrollListener listener) {
onGesturesManagerInteractionListener.onRemoveScrollListener(listener);
}
@@ -1930,9 +1805,8 @@ public final class MapboxMap {
* Adds a callback that's invoked when the map is flinged.
*
* @param listener The callback that's invoked when the map is flinged.
* To unset the callback, use null.
*/
public void addOnFlingListener(@Nullable OnFlingListener listener) {
public void addOnFlingListener(@NonNull OnFlingListener listener) {
onGesturesManagerInteractionListener.onAddFlingListener(listener);
}
@@ -1940,9 +1814,8 @@ public final class MapboxMap {
* Removes a callback that's invoked when the map is flinged.
*
* @param listener The callback that's invoked when the map is flinged.
* To unset the callback, use null.
*/
public void removeOnFlingListener(@Nullable OnFlingListener listener) {
public void removeOnFlingListener(@NonNull OnFlingListener listener) {
onGesturesManagerInteractionListener.onRemoveFlingListener(listener);
}
@@ -1951,7 +1824,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is moved.
*/
public void addOnMoveListener(OnMoveListener listener) {
public void addOnMoveListener(@NonNull OnMoveListener listener) {
onGesturesManagerInteractionListener.onAddMoveListener(listener);
}
@@ -1960,7 +1833,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is moved.
*/
public void removeOnMoveListener(OnMoveListener listener) {
public void removeOnMoveListener(@NonNull OnMoveListener listener) {
onGesturesManagerInteractionListener.onRemoveMoveListener(listener);
}
@@ -1969,7 +1842,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is rotated.
*/
public void addOnRotateListener(OnRotateListener listener) {
public void addOnRotateListener(@NonNull OnRotateListener listener) {
onGesturesManagerInteractionListener.onAddRotateListener(listener);
}
@@ -1978,7 +1851,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is rotated.
*/
public void removeOnRotateListener(OnRotateListener listener) {
public void removeOnRotateListener(@NonNull OnRotateListener listener) {
onGesturesManagerInteractionListener.onRemoveRotateListener(listener);
}
@@ -1987,7 +1860,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is scaled.
*/
public void addOnScaleListener(OnScaleListener listener) {
public void addOnScaleListener(@NonNull OnScaleListener listener) {
onGesturesManagerInteractionListener.onAddScaleListener(listener);
}
@@ -1996,7 +1869,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is scaled.
*/
public void removeOnScaleListener(OnScaleListener listener) {
public void removeOnScaleListener(@NonNull OnScaleListener listener) {
onGesturesManagerInteractionListener.onRemoveScaleListener(listener);
}
@@ -2005,7 +1878,7 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is tilted.
*/
public void addOnShoveListener(OnShoveListener listener) {
public void addOnShoveListener(@NonNull OnShoveListener listener) {
onGesturesManagerInteractionListener.onAddShoveListener(listener);
}
@@ -2014,22 +1887,30 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the map is tilted.
*/
public void removeOnShoveListener(OnShoveListener listener) {
public void removeOnShoveListener(@NonNull OnShoveListener listener) {
onGesturesManagerInteractionListener.onRemoveShoveListener(listener);
}
/**
* Sets a custom {@link AndroidGesturesManager} to handle {@link android.view.MotionEvent}s registered by the map.
* Sets a custom {@link AndroidGesturesManager} to handle {@link android.view.MotionEvent}s
* registered by the {@link MapView}.
*
* @param androidGesturesManager Gestures manager that interprets gestures based on the motion events.
* @param androidGesturesManager Gestures manager that interprets gestures based on the motion events.
* @param attachDefaultListeners If true, pre-defined listeners will be attach
* to change map based on {@link AndroidGesturesManager} callbacks.
* @param setDefaultMutuallyExclusives If true, pre-defined mutually exclusive gesture sets
* 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) {
onGesturesManagerInteractionListener.setGesturesManager(androidGesturesManager);
public void setGesturesManager(AndroidGesturesManager androidGesturesManager, boolean attachDefaultListeners,
boolean setDefaultMutuallyExclusives) {
onGesturesManagerInteractionListener.setGesturesManager(
androidGesturesManager, attachDefaultListeners, setDefaultMutuallyExclusives);
}
/**
* Get current {@link AndroidGesturesManager} that handles {@link android.view.MotionEvent}s registered by the map.
* Get current {@link AndroidGesturesManager} that handles {@link android.view.MotionEvent}s
* registered by the {@link MapView}
*
* @return Current gestures manager.
*/
@@ -2037,6 +1918,13 @@ public final class MapboxMap {
return onGesturesManagerInteractionListener.getGesturesManager();
}
/**
* Interrupts any ongoing gesture velocity animations.
*/
public void cancelAllVelocityAnimations() {
onGesturesManagerInteractionListener.cancelAllVelocityAnimations();
}
/**
* Sets a callback that's invoked when the user clicks on the map view.
*
@@ -2053,9 +1941,8 @@ public final class MapboxMap {
* Adds a callback that's invoked when the user clicks on the map view.
*
* @param listener The callback that's invoked when the user clicks on the map view.
* To unset the callback, use null.
*/
public void addOnMapClickListener(@Nullable OnMapClickListener listener) {
public void addOnMapClickListener(@NonNull OnMapClickListener listener) {
onGesturesManagerInteractionListener.onAddMapClickListener(listener);
}
@@ -2063,9 +1950,8 @@ public final class MapboxMap {
* Removes a callback that's invoked when the user clicks on the map view.
*
* @param listener The callback that's invoked when the user clicks on the map view.
* To unset the callback, use null.
*/
public void removeOnMapClickListener(@Nullable OnMapClickListener listener) {
public void removeOnMapClickListener(@NonNull OnMapClickListener listener) {
onGesturesManagerInteractionListener.onRemoveMapClickListener(listener);
}
@@ -2085,9 +1971,8 @@ public final class MapboxMap {
* Adds a callback that's invoked when the user long clicks on the map view.
*
* @param listener The callback that's invoked when the user long clicks on the map view.
* To unset the callback, use null.
*/
public void addOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
public void addOnMapLongClickListener(@NonNull OnMapLongClickListener listener) {
onGesturesManagerInteractionListener.onAddMapLongClickListener(listener);
}
@@ -2095,9 +1980,8 @@ public final class MapboxMap {
* Removes a callback that's invoked when the user long clicks on the map view.
*
* @param listener The callback that's invoked when the user long clicks on the map view.
* To unset the callback, use null.
*/
public void removeOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
public void removeOnMapLongClickListener(@NonNull OnMapLongClickListener listener) {
onGesturesManagerInteractionListener.onRemoveMapLongClickListener(listener);
}
@@ -2158,107 +2042,6 @@ public final class MapboxMap {
return annotationManager.getInfoWindowManager().getOnInfoWindowCloseListener();
}
//
// User location
//
/**
* Returns the status of the my-location layer.
*
* @return True if the my-location layer is enabled, false otherwise.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public boolean isMyLocationEnabled() {
return trackingSettings.isMyLocationEnabled();
}
/**
* <p>
* Enables or disables the my-location layer.
* While enabled, the my-location layer continuously draws an indication of a user's current
* location and bearing.
* </p>
* In order to use the my-location layer feature you need to request permission for either
* android.Manifest.permission#ACCESS_COARSE_LOCATION or android.Manifest.permission#ACCESS_FINE_LOCATION.
*
* @param enabled True to enable; false to disable.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public void setMyLocationEnabled(boolean enabled) {
trackingSettings.setMyLocationEnabled(enabled);
}
/**
* Returns the currently displayed user location, or null if there is no location data available.
*
* @return The currently displayed user location.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Nullable
@Deprecated
public Location getMyLocation() {
return trackingSettings.getMyLocation();
}
/**
* Sets a callback that's invoked when the the My Location view
* (which signifies the user's location) changes location.
*
* @param listener The callback that's invoked when the user clicks on a marker.
* To unset the callback, use null.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener
listener) {
trackingSettings.setOnMyLocationChangeListener(listener);
}
/**
* Replaces the location source of the my-location layer.
*
* @param locationSource A {@link LocationEngine} location source to use in the my-location layer.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public void setLocationSource(@Nullable LocationEngine locationSource) {
trackingSettings.setLocationSource(locationSource);
}
/**
* Sets a callback that's invoked when the location tracking mode changes.
*
* @param listener The callback that's invoked when the location tracking mode changes.
* To unset the callback, use null.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public void setOnMyLocationTrackingModeChangeListener(
@Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
trackingSettings.setOnMyLocationTrackingModeChangeListener(listener);
}
/**
* Sets a callback that's invoked when the bearing tracking mode changes.
*
* @param listener The callback that's invoked when the bearing tracking mode changes.
* To unset the callback, use null.
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-locationlayer instead.
*/
@Deprecated
public void setOnMyBearingTrackingModeChangeListener(@Nullable OnMyBearingTrackingModeChangeListener listener) {
trackingSettings.setOnMyBearingTrackingModeChangeListener(listener);
}
//
// Invalidate
//
@@ -2289,13 +2072,13 @@ public final class MapboxMap {
* Queries the map for rendered features
*
* @param coordinates the point to query
* @param filter filters the returned features
* @param filter filters the returned features with an expression
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates,
@Nullable Filter.Statement filter,
@Nullable Expression filter,
@Nullable String... layerIds) {
return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter);
}
@@ -2317,26 +2100,17 @@ public final class MapboxMap {
* Queries the map for rendered features
*
* @param coordinates the box to query
* @param filter filters the returned features
* @param filter filters the returned features with an expression
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates,
@Nullable Filter.Statement filter,
@Nullable Expression filter,
@Nullable String... layerIds) {
return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter);
}
FocalPointChangeListener createFocalPointChangeListener() {
return new FocalPointChangeListener() {
@Override
public void onFocalPointChanged(PointF pointF) {
focalPoint = pointF;
}
};
}
//
// Interfaces
//
@@ -2564,7 +2338,10 @@ public final class MapboxMap {
AndroidGesturesManager getGesturesManager();
void setGesturesManager(AndroidGesturesManager gesturesManager);
void setGesturesManager(AndroidGesturesManager gesturesManager, boolean attachDefaultListeners,
boolean setDefaultMutuallyExclusives);
void cancelAllVelocityAnimations();
}
/**
@@ -2836,51 +2613,6 @@ public final class MapboxMap {
boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, @NonNull MarkerViewAdapter adapter);
}
/**
* Interface definition for a callback to be invoked when the the My Location view changes location.
*
* @see MapboxMap#setOnMyLocationChangeListener(OnMyLocationChangeListener)
*/
public interface OnMyLocationChangeListener {
/**
* Called when the location of the My Location view has changed
* (be it latitude/longitude, bearing or accuracy).
*
* @param location The current location of the My Location view The type of map change event.
*/
void onMyLocationChange(@Nullable Location location);
}
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
* @see TrackingSettings#setMyLocationTrackingMode(int)
*/
public interface OnMyLocationTrackingModeChangeListener {
/**
* Called when the tracking mode of My Location tracking has changed
*
* @param myLocationTrackingMode the current active location tracking mode
*/
void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode);
}
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
* @see TrackingSettings#setMyLocationTrackingMode(int)
*/
public interface OnMyBearingTrackingModeChangeListener {
/**
* Called when the tracking mode of My Bearing tracking has changed
*
* @param myBearingTrackingMode the current active bearing tracking mode
*/
void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode);
}
/**
* Interface definition for a callback to be invoked when a task is complete or cancelled.
*/

View File

@@ -8,10 +8,8 @@ import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -20,7 +18,6 @@ import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import com.mapbox.mapboxsdk.utils.ColorUtils;
import java.util.Arrays;
@@ -68,18 +65,6 @@ public class MapboxMapOptions implements Parcelable {
private boolean zoomControlsEnabled = false;
private boolean doubleTapGesturesEnabled = true;
private boolean myLocationEnabled;
private Drawable myLocationForegroundDrawable;
private Drawable myLocationForegroundBearingDrawable;
private Drawable myLocationBackgroundDrawable;
@ColorInt
private int myLocationForegroundTintColor = UNDEFINED_COLOR;
@ColorInt
private int myLocationBackgroundTintColor = UNDEFINED_COLOR;
private int[] myLocationBackgroundPadding;
private int myLocationAccuracyTintColor;
private int myLocationAccuracyAlpha;
private float myLocationAccuracyThreshold;
private boolean prefetchesTiles = true;
private boolean zMediaOverlay = false;
private String localIdeographFontFamily;
@@ -87,6 +72,7 @@ public class MapboxMapOptions implements Parcelable {
private String apiBaseUrl;
private boolean textureMode;
private boolean translucentTextureSurface;
private String style;
@@ -129,33 +115,10 @@ public class MapboxMapOptions implements Parcelable {
zoomGesturesEnabled = in.readByte() != 0;
doubleTapGesturesEnabled = in.readByte() != 0;
myLocationEnabled = in.readByte() != 0;
Bitmap foregroundBitmap = in.readParcelable(getClass().getClassLoader());
if (foregroundBitmap != null) {
myLocationForegroundDrawable = new BitmapDrawable(foregroundBitmap);
}
Bitmap foregroundBearingBitmap = in.readParcelable(getClass().getClassLoader());
if (foregroundBearingBitmap != null) {
myLocationForegroundBearingDrawable = new BitmapDrawable(foregroundBearingBitmap);
}
Bitmap backgroundBitmap = in.readParcelable(getClass().getClassLoader());
if (backgroundBitmap != null) {
myLocationBackgroundDrawable = new BitmapDrawable(backgroundBitmap);
}
myLocationForegroundTintColor = in.readInt();
myLocationBackgroundTintColor = in.readInt();
myLocationBackgroundPadding = in.createIntArray();
myLocationAccuracyAlpha = in.readInt();
myLocationAccuracyTintColor = in.readInt();
myLocationAccuracyThreshold = in.readFloat();
style = in.readString();
apiBaseUrl = in.readString();
textureMode = in.readByte() != 0;
translucentTextureSurface = in.readByte() != 0;
prefetchesTiles = in.readByte() != 0;
zMediaOverlay = in.readByte() != 0;
localIdeographFontFamily = in.readString();
@@ -245,50 +208,10 @@ public class MapboxMapOptions implements Parcelable {
(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginBottom,
FOUR_DP * pxlRatio))});
mapboxMapOptions.locationEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_myLocation, false));
mapboxMapOptions.myLocationForegroundTintColor(
typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationTintColor, UNDEFINED_COLOR));
mapboxMapOptions.myLocationBackgroundTintColor(
typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundTintColor, UNDEFINED_COLOR));
Drawable foregroundDrawable = typedArray.getDrawable(R.styleable.mapbox_MapView_mapbox_myLocationDrawable);
if (foregroundDrawable == null) {
foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
}
Drawable foregroundBearingDrawable = typedArray.getDrawable(
R.styleable.mapbox_MapView_mapbox_myLocationBearingDrawable);
if (foregroundBearingDrawable == null) {
foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
}
Drawable backgroundDrawable = typedArray.getDrawable(
R.styleable.mapbox_MapView_mapbox_myLocationBackgroundDrawable);
if (backgroundDrawable == null) {
backgroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape);
}
mapboxMapOptions.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
mapboxMapOptions.myLocationBackgroundDrawable(backgroundDrawable);
mapboxMapOptions.myLocationBackgroundPadding(new int[] {
(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginLeft,
0) * pxlRatio),
(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginTop,
0) * pxlRatio),
(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginRight,
0) * pxlRatio),
(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginBottom,
0) * pxlRatio)
});
mapboxMapOptions.myLocationAccuracyAlpha(
typedArray.getInt(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyAlpha, 100));
mapboxMapOptions.myLocationAccuracyTint(
typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyTintColor,
ColorUtils.getPrimaryColor(context)));
mapboxMapOptions.myLocationAccuracyThreshold(
typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyThreshold, 0));
mapboxMapOptions.textureMode(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_renderTextureMode, false));
mapboxMapOptions.translucentTextureSurface(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_renderTextureTranslucentSurface, false));
mapboxMapOptions.setPrefetchesTiles(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_enableTilePrefetch, true));
mapboxMapOptions.renderSurfaceOnTop(
@@ -571,128 +494,6 @@ public class MapboxMapOptions implements Parcelable {
return this;
}
/**
* Specifies if the user location view is enabled for a map view.
*
* @param locationEnabled True and gesture will be enabled
* @return This
*/
public MapboxMapOptions locationEnabled(boolean locationEnabled) {
this.myLocationEnabled = locationEnabled;
return this;
}
/**
* Set the foreground drawables of the MyLocationView.
*
* @param myLocationForegroundDrawable the drawable to show as foreground without bearing
* @param myLocationBearingDrawable the drawable to show as foreground when bearing is disabled
* @return This
*/
public MapboxMapOptions myLocationForegroundDrawables(Drawable myLocationForegroundDrawable,
Drawable myLocationBearingDrawable) {
this.myLocationForegroundDrawable = myLocationForegroundDrawable;
this.myLocationForegroundBearingDrawable = myLocationBearingDrawable;
return this;
}
/**
* Set the foreground drawable of the MyLocationView.
* <p>
* The same drawable will be used for both bearing as non bearing modes.
* </p>
*
* @param myLocationForegroundDrawable the drawable to show as foreground
* @return This
*/
public MapboxMapOptions myLocationForegroundDrawable(Drawable myLocationForegroundDrawable) {
this.myLocationForegroundDrawable = myLocationForegroundDrawable;
return this;
}
/**
* Set the background drawable of MyLocationView.
* <p>
* Padding can be added to provide an offset to the background.
* </p>
*
* @param myLocationBackgroundDrawable the drawable to show as background
* @return This
*/
public MapboxMapOptions myLocationBackgroundDrawable(Drawable myLocationBackgroundDrawable) {
this.myLocationBackgroundDrawable = myLocationBackgroundDrawable;
return this;
}
/**
* Set the foreground tint color of MyLocationView.
* <p>
* The color will tint both the foreground and the bearing foreground drawable.
* </p>
*
* @param myLocationForegroundTintColor the color to tint the foreground drawable
* @return This
*/
public MapboxMapOptions myLocationForegroundTintColor(@ColorInt int myLocationForegroundTintColor) {
this.myLocationForegroundTintColor = myLocationForegroundTintColor;
return this;
}
/**
* Set the background tint color of MyLocationView.
*
* @param myLocationBackgroundTintColor the color to tint the background drawable
* @return This
*/
public MapboxMapOptions myLocationBackgroundTintColor(@ColorInt int myLocationBackgroundTintColor) {
this.myLocationBackgroundTintColor = myLocationBackgroundTintColor;
return this;
}
/**
* Set the MyLocationView padding.
*
* @param myLocationBackgroundPadding the color to tint the background
* @return This
*/
public MapboxMapOptions myLocationBackgroundPadding(int[] myLocationBackgroundPadding) {
this.myLocationBackgroundPadding = myLocationBackgroundPadding;
return this;
}
/**
* Set the MyLocationView accuracy circle tint color.
*
* @param myLocationAccuracyTintColor the color to tint the accuracy circle
* @return This
*/
public MapboxMapOptions myLocationAccuracyTint(@ColorInt int myLocationAccuracyTintColor) {
this.myLocationAccuracyTintColor = myLocationAccuracyTintColor;
return this;
}
/**
* Set the MyLocationView accuracy alpha value.
*
* @param alpha the alpha value
* @return This
*/
public MapboxMapOptions myLocationAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) {
this.myLocationAccuracyAlpha = alpha;
return this;
}
/**
* Set accuracy circle threshold. Circle won't be displayed if accuracy is below set value.
*
* @param myLocationAccuracyThreshold Value of accuracy (in meters), below which circle won't be displayed
* @return This
*/
public MapboxMapOptions myLocationAccuracyThreshold(float myLocationAccuracyThreshold) {
this.myLocationAccuracyThreshold = myLocationAccuracyThreshold;
return this;
}
/**
* Enable {@link android.view.TextureView} as rendered surface.
* <p>
@@ -711,6 +512,11 @@ public class MapboxMapOptions implements Parcelable {
return this;
}
public MapboxMapOptions translucentTextureSurface(boolean translucentTextureSurface) {
this.translucentTextureSurface = translucentTextureSurface;
return this;
}
/**
* Enable tile pre-fetching. Loads tiles at a lower zoom-level to pre-render
* a low resolution preview while more detailed tiles are loaded.
@@ -725,11 +531,11 @@ public class MapboxMapOptions implements Parcelable {
}
/**
* Set the font family for generating glyphs locally for ideographs in the ‘CJK Unified Ideographs’
* and ‘Hangul Syllables’ ranges.
*
* Set the font family for generating glyphs locally for ideographs in the &#x27;CJK Unified Ideographs&#x27;
* and &#x27;Hangul Syllables&#x27; ranges.
* <p>
* The font family argument is passed to {@link android.graphics.Typeface#create(String, int)}.
* Default system fonts are defined in '/system/etc/fonts.xml'
* Default system fonts are defined in &#x27;/system/etc/fonts.xml&#x27;
*
* @param fontFamily font family for local ideograph generation.
* @return This
@@ -975,98 +781,6 @@ public class MapboxMapOptions implements Parcelable {
return attributionTintColor;
}
/**
* Get the current configured user location view state for a map view.
*
* @return True and user location will be shown
*/
public boolean getLocationEnabled() {
return myLocationEnabled;
}
/**
* Get the current configured MyLocationView foreground drawable.
*
* @return the drawable used as foreground
*/
public Drawable getMyLocationForegroundDrawable() {
return myLocationForegroundDrawable;
}
/**
* Get the current configured MyLocationView foreground bearing drawable.
*
* @return the drawable used as foreground when bearing is enabled
*/
public Drawable getMyLocationForegroundBearingDrawable() {
return myLocationForegroundBearingDrawable;
}
/**
* Get the current configured MyLocationView background drawable.
*
* @return the drawable used as background
*/
public Drawable getMyLocationBackgroundDrawable() {
return myLocationBackgroundDrawable;
}
/**
* Get the current configured MyLocationView foreground tint color.
*
* @return the tint color
*/
@ColorInt
public int getMyLocationForegroundTintColor() {
return myLocationForegroundTintColor;
}
/**
* Get the current configured MyLocationView background tint color.
*
* @return the tint color
*/
@ColorInt
public int getMyLocationBackgroundTintColor() {
return myLocationBackgroundTintColor;
}
/**
* Get the current configured MyLocationView background padding.
*
* @return an array describing the padding in a LTRB manner
*/
public int[] getMyLocationBackgroundPadding() {
return myLocationBackgroundPadding;
}
/**
* Get the current configured MyLocationView accuracy circle color tint value.
*
* @return the tint color
*/
public int getMyLocationAccuracyTintColor() {
return myLocationAccuracyTintColor;
}
/**
* Get the current configured MyLocationView accuracy circle alpha value.
*
* @return the alpha value
*/
public int getMyLocationAccuracyAlpha() {
return myLocationAccuracyAlpha;
}
/**
* Returns current accuracy threshold value (in meters).
*
* @return Value of accuracy threshold (in meters), below which circle won't be displayed
*/
public float getMyLocationAccuracyThreshold() {
return myLocationAccuracyThreshold;
}
/**
* Get the current configured debug state for a map view.
*
@@ -1085,9 +799,13 @@ public class MapboxMapOptions implements Parcelable {
return textureMode;
}
public boolean getTranslucentTextureSurface() {
return translucentTextureSurface;
}
/**
* Returns the font-family for locally overriding generation of glyphs in the
* ‘CJK Unified Ideographs’ and ‘Hangul Syllables’ ranges.
* &#x27;CJK Unified Ideographs&#x27; and &#x27;Hangul Syllables&#x27; ranges.
*
* @return Local ideograph font family name.
*/
@@ -1141,24 +859,10 @@ public class MapboxMapOptions implements Parcelable {
dest.writeByte((byte) (zoomGesturesEnabled ? 1 : 0));
dest.writeByte((byte) (doubleTapGesturesEnabled ? 1 : 0));
dest.writeByte((byte) (myLocationEnabled ? 1 : 0));
dest.writeParcelable(myLocationForegroundDrawable != null
? BitmapUtils.getBitmapFromDrawable(myLocationForegroundDrawable) : null, flags);
dest.writeParcelable(myLocationForegroundBearingDrawable != null
? BitmapUtils.getBitmapFromDrawable(myLocationForegroundBearingDrawable) : null, flags);
dest.writeParcelable(myLocationBackgroundDrawable != null
? BitmapUtils.getBitmapFromDrawable(myLocationBackgroundDrawable) : null, flags);
dest.writeInt(myLocationForegroundTintColor);
dest.writeInt(myLocationBackgroundTintColor);
dest.writeIntArray(myLocationBackgroundPadding);
dest.writeInt(myLocationAccuracyAlpha);
dest.writeInt(myLocationAccuracyTintColor);
dest.writeFloat(myLocationAccuracyThreshold);
dest.writeString(style);
dest.writeString(apiBaseUrl);
dest.writeByte((byte) (textureMode ? 1 : 0));
dest.writeByte((byte) (translucentTextureSurface ? 1 : 0));
dest.writeByte((byte) (prefetchesTiles ? 1 : 0));
dest.writeByte((byte) (zMediaOverlay ? 1 : 0));
dest.writeString(localIdeographFontFamily);
@@ -1231,24 +935,6 @@ public class MapboxMapOptions implements Parcelable {
if (doubleTapGesturesEnabled != options.doubleTapGesturesEnabled) {
return false;
}
if (myLocationEnabled != options.myLocationEnabled) {
return false;
}
if (myLocationForegroundTintColor != options.myLocationForegroundTintColor) {
return false;
}
if (myLocationBackgroundTintColor != options.myLocationBackgroundTintColor) {
return false;
}
if (myLocationAccuracyTintColor != options.myLocationAccuracyTintColor) {
return false;
}
if (myLocationAccuracyAlpha != options.myLocationAccuracyAlpha) {
return false;
}
if (myLocationAccuracyThreshold != options.myLocationAccuracyThreshold) {
return false;
}
if (cameraPosition != null ? !cameraPosition.equals(options.cameraPosition) : options.cameraPosition != null) {
return false;
}
@@ -1261,24 +947,6 @@ public class MapboxMapOptions implements Parcelable {
if (!Arrays.equals(attributionMargins, options.attributionMargins)) {
return false;
}
if (myLocationForegroundDrawable != null
? !myLocationForegroundDrawable.equals(options.myLocationForegroundDrawable)
: options.myLocationForegroundDrawable != null) {
return false;
}
if (myLocationForegroundBearingDrawable != null
? !myLocationForegroundBearingDrawable.equals(options.myLocationForegroundBearingDrawable)
: options.myLocationForegroundBearingDrawable != null) {
return false;
}
if (myLocationBackgroundDrawable != null
? !myLocationBackgroundDrawable.equals(options.myLocationBackgroundDrawable)
: options.myLocationBackgroundDrawable != null) {
return false;
}
if (!Arrays.equals(myLocationBackgroundPadding, options.myLocationBackgroundPadding)) {
return false;
}
if (style != null ? !style.equals(options.style) : options.style != null) {
return false;
}
@@ -1326,20 +994,9 @@ public class MapboxMapOptions implements Parcelable {
result = 31 * result + (zoomGesturesEnabled ? 1 : 0);
result = 31 * result + (zoomControlsEnabled ? 1 : 0);
result = 31 * result + (doubleTapGesturesEnabled ? 1 : 0);
result = 31 * result + (myLocationEnabled ? 1 : 0);
result = 31 * result + (myLocationForegroundDrawable != null ? myLocationForegroundDrawable.hashCode() : 0);
result = 31 * result + (myLocationForegroundBearingDrawable != null
? myLocationForegroundBearingDrawable.hashCode() : 0);
result = 31 * result + (myLocationBackgroundDrawable != null ? myLocationBackgroundDrawable.hashCode() : 0);
result = 31 * result + myLocationForegroundTintColor;
result = 31 * result + myLocationBackgroundTintColor;
result = 31 * result + Arrays.hashCode(myLocationBackgroundPadding);
result = 31 * result + myLocationAccuracyTintColor;
result = 31 * result + myLocationAccuracyAlpha;
result = 31 * result + (myLocationAccuracyThreshold != +0.0f
? Float.floatToIntBits(myLocationAccuracyThreshold) : 0);
result = 31 * result + (apiBaseUrl != null ? apiBaseUrl.hashCode() : 0);
result = 31 * result + (textureMode ? 1 : 0);
result = 31 * result + (translucentTextureSurface ? 1 : 0);
result = 31 * result + (style != null ? style.hashCode() : 0);
result = 31 * result + (prefetchesTiles ? 1 : 0);
result = 31 * result + (zMediaOverlay ? 1 : 0);

View File

@@ -24,8 +24,8 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
import com.mapbox.mapboxsdk.maps.renderer.MapRenderer;
import com.mapbox.mapboxsdk.storage.FileSource;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException;
import com.mapbox.mapboxsdk.style.layers.Filter;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.light.Light;
import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException;
@@ -229,18 +229,28 @@ final class NativeMapView {
return nativeGetLatLng().wrap();
}
public CameraPosition getCameraForLatLngBounds(LatLngBounds latLngBounds) {
public CameraPosition getCameraForLatLngBounds(LatLngBounds latLngBounds, int[] padding) {
if (isDestroyedOn("getCameraForLatLngBounds")) {
return null;
}
return nativeGetCameraForLatLngBounds(latLngBounds);
return nativeGetCameraForLatLngBounds(
latLngBounds,
padding[1] / pixelRatio,
padding[0] / pixelRatio,
padding[3] / pixelRatio,
padding[2] / pixelRatio);
}
public CameraPosition getCameraForGeometry(Geometry geometry, double bearing) {
public CameraPosition getCameraForGeometry(Geometry geometry, double bearing, int[] padding) {
if (isDestroyedOn("getCameraForGeometry")) {
return null;
}
return nativeGetCameraForGeometry(geometry, bearing);
return nativeGetCameraForGeometry(
geometry, bearing,
padding[1] / pixelRatio,
padding[0] / pixelRatio,
padding[3] / pixelRatio,
padding[2] / pixelRatio);
}
public void resetPosition() {
@@ -758,20 +768,8 @@ final class NativeMapView {
return;
}
// Check/correct config
if (image.getConfig() != Bitmap.Config.ARGB_8888) {
image = image.copy(Bitmap.Config.ARGB_8888, false);
}
// Get pixels
ByteBuffer buffer = ByteBuffer.allocate(image.getByteCount());
image.copyPixelsToBuffer(buffer);
// Determine pixel ratio
float density = image.getDensity() == Bitmap.DENSITY_NONE ? Bitmap.DENSITY_NONE : image.getDensity();
float pixelRatio = density / DisplayMetrics.DENSITY_DEFAULT;
nativeAddImage(name, image.getWidth(), image.getHeight(), pixelRatio, buffer.array());
nativeAddImage(name, image, image.getDensity() / DisplayMetrics.DENSITY_DEFAULT);
}
public void addImages(@NonNull HashMap<String, Bitmap> bitmapHashMap) {
@@ -801,7 +799,7 @@ final class NativeMapView {
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates,
@Nullable String[] layerIds,
@Nullable Filter.Statement filter) {
@Nullable Expression filter) {
if (isDestroyedOn("queryRenderedFeatures")) {
return new ArrayList<>();
}
@@ -813,7 +811,7 @@ final class NativeMapView {
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates,
@Nullable String[] layerIds,
@Nullable Filter.Statement filter) {
@Nullable Expression filter) {
if (isDestroyedOn("queryRenderedFeatures")) {
return new ArrayList<>();
}
@@ -908,9 +906,11 @@ final class NativeMapView {
private native LatLng nativeGetLatLng();
private native CameraPosition nativeGetCameraForLatLngBounds(LatLngBounds latLngBounds);
private native CameraPosition nativeGetCameraForLatLngBounds(
LatLngBounds latLngBounds, double top, double left, double bottom, double right);
private native CameraPosition nativeGetCameraForGeometry(Geometry geometry, double bearing);
private native CameraPosition nativeGetCameraForGeometry(
Geometry geometry, double bearing, double top, double left, double bottom, double right);
private native void nativeResetPosition();
@@ -1032,8 +1032,7 @@ final class NativeMapView {
private native void nativeRemoveSource(Source source, long sourcePtr);
private native void nativeAddImage(String name, int width, int height, float pixelRatio,
byte[] array);
private native void nativeAddImage(String name, Bitmap bitmap, float pixelRatio);
private native void nativeAddImages(Image[] images);

View File

@@ -9,6 +9,9 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
import com.mapbox.mapboxsdk.geometry.VisibleRegion;
import java.util.ArrayList;
import java.util.List;
/**
* A projection is used to translate between on screen location and geographic coordinates on
* the surface of the Earth. Screen location is in screen pixels (not display pixels)
@@ -24,25 +27,17 @@ public class Projection {
this.contentPadding = new int[] {0, 0, 0, 0};
}
void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
void setContentPadding(int[] contentPadding) {
this.contentPadding = contentPadding;
int[] padding = new int[] {
contentPadding[0] + userLocationViewPadding[0],
contentPadding[1] + userLocationViewPadding[1],
contentPadding[2] + userLocationViewPadding[2],
contentPadding[3] + userLocationViewPadding[3]
};
nativeMapView.setContentPadding(padding);
nativeMapView.setContentPadding(contentPadding);
}
int[] getContentPadding() {
return contentPadding;
}
public void invalidateContentPadding(int[] userLocationViewPadding) {
setContentPadding(contentPadding, userLocationViewPadding);
public void invalidateContentPadding() {
setContentPadding(contentPadding);
}
/**
@@ -103,14 +98,49 @@ public class Projection {
LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));
return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight,
new LatLngBounds.Builder()
.include(topRight)
.include(bottomLeft)
.include(bottomRight)
.include(topLeft)
.build()
);
// Map can be rotated, find correct LatLngBounds that encompasses the visible region (that might be rotated)
List<LatLng> boundsPoints = new ArrayList<>();
boundsPoints.add(topLeft);
boundsPoints.add(topRight);
boundsPoints.add(bottomRight);
boundsPoints.add(bottomLeft);
// order so that two most northern point are put first
while ((boundsPoints.get(0).getLatitude() < boundsPoints.get(3).getLatitude())
|| (boundsPoints.get(1).getLatitude() < boundsPoints.get(2).getLatitude())) {
LatLng first = boundsPoints.remove(0);
boundsPoints.add(first);
}
double north = boundsPoints.get(0).getLatitude();
if (north < boundsPoints.get(1).getLatitude()) {
north = boundsPoints.get(1).getLatitude();
}
double south = boundsPoints.get(2).getLatitude();
if (south > boundsPoints.get(3).getLatitude()) {
south = boundsPoints.get(3).getLatitude();
}
double firstLon = boundsPoints.get(0).getLongitude();
double secondLon = boundsPoints.get(1).getLongitude();
double thridLon = boundsPoints.get(2).getLongitude();
double fourthLon = boundsPoints.get(3).getLongitude();
// if it does not go over the date line
if (secondLon > fourthLon && firstLon < thridLon) {
return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight,
LatLngBounds.from(north,
secondLon > thridLon ? secondLon : thridLon,
south,
firstLon < fourthLon ? firstLon : fourthLon));
} else {
return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight,
LatLngBounds.from(north,
secondLon < thridLon ? secondLon : thridLon,
south,
firstLon > fourthLon ? firstLon : fourthLon));
}
}
/**

View File

@@ -2,11 +2,12 @@ package com.mapbox.mapboxsdk.maps;
import com.mapbox.android.telemetry.MapboxTelemetry;
import com.mapbox.android.telemetry.SessionInterval;
import com.mapbox.android.telemetry.TelemetryEnabler;
import com.mapbox.mapboxsdk.BuildConfig;
import com.mapbox.mapboxsdk.Mapbox;
class Events {
public class Telemetry {
static final String TWO_FINGER_TAP = "TwoFingerTap";
static final String DOUBLE_TAP = "DoubleTap";
static final String SINGLE_TAP = "SingleTap";
@@ -16,21 +17,32 @@ class Events {
static final String PITCH = "Pitch";
private MapboxTelemetry telemetry;
private Events() {
private Telemetry() {
telemetry = new MapboxTelemetry(Mapbox.getApplicationContext(), Mapbox.getAccessToken(),
BuildConfig.MAPBOX_EVENTS_USER_AGENT);
TelemetryEnabler.State telemetryState = TelemetryEnabler.retrieveTelemetryStateFromPreferences();
if (TelemetryEnabler.State.NOT_INITIALIZED.equals(telemetryState)
|| TelemetryEnabler.State.ENABLED.equals(telemetryState)) {
if (TelemetryEnabler.State.ENABLED.equals(telemetryState)) {
telemetry.enable();
}
}
private static class EventsHolder {
private static final Events INSTANCE = new Events();
public static void initialize() {
obtainTelemetry();
}
public static void updateDebugLoggingEnabled(boolean debugLoggingEnabled) {
TelemetryHolder.INSTANCE.telemetry.updateDebugLoggingEnabled(debugLoggingEnabled);
}
public static boolean updateSessionIdRotationInterval(SessionInterval interval) {
return TelemetryHolder.INSTANCE.telemetry.updateSessionIdRotationInterval(interval);
}
private static class TelemetryHolder {
private static final Telemetry INSTANCE = new Telemetry();
}
static MapboxTelemetry obtainTelemetry() {
return EventsHolder.INSTANCE.telemetry;
return TelemetryHolder.INSTANCE.telemetry;
}
}

View File

@@ -1,419 +0,0 @@
package com.mapbox.mapboxsdk.maps;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import com.mapbox.android.core.location.LocationEngine;
import com.mapbox.android.core.location.LocationEngineListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import timber.log.Timber;
/**
* Settings for the user location and bearing tracking of a MapboxMap.
*
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
@Deprecated
public final class TrackingSettings {
private final MyLocationView myLocationView;
private final UiSettings uiSettings;
private final FocalPointChangeListener focalPointChangedListener;
private final CameraZoomInvalidator zoomInvalidator;
private LocationEngine locationSource;
private LocationEngineListener myLocationListener;
private boolean locationChangeAnimationEnabled = true;
private boolean isCustomLocationSource;
private boolean myLocationEnabled;
private boolean dismissLocationTrackingOnGesture = true;
private boolean dismissBearingTrackingOnGesture = true;
private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings,
FocalPointChangeListener focalPointChangedListener, CameraZoomInvalidator zoomInvalidator) {
this.myLocationView = myLocationView;
this.focalPointChangedListener = focalPointChangedListener;
this.uiSettings = uiSettings;
this.zoomInvalidator = zoomInvalidator;
}
void initialise(MapboxMapOptions options) {
locationSource = Mapbox.getLocationEngine();
setMyLocationEnabled(options.getLocationEnabled());
}
void onSaveInstanceState(Bundle outState) {
outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, getMyLocationTrackingMode());
outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, getMyBearingTrackingMode());
outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, isDismissLocationTrackingOnGesture());
outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture());
outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled());
outState.putBoolean(MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, isLocationChangeAnimationEnabled());
outState.putBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE, isCustomLocationSource());
}
void onRestoreInstanceState(Bundle savedInstanceState) {
try {
setMyLocationEnabled(
savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED),
savedInstanceState.getBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE)
);
} catch (SecurityException ignore) {
// User did not accept location permissions
}
// noinspection ResourceType
setMyLocationTrackingMode(savedInstanceState.getInt(
MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
// noinspection ResourceType
setMyBearingTrackingMode(savedInstanceState.getInt(
MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
setDismissLocationTrackingOnGesture(savedInstanceState.getBoolean(
MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true));
setDismissBearingTrackingOnGesture(savedInstanceState.getBoolean(
MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true));
setLocationChangeAnimationEnabled(savedInstanceState.getBoolean(
MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, true));
}
/**
* <p>
* Set the current my location tracking mode.
* </p>
* <p>
* Will enable my location if not active.
* </p>
* See {@link MyLocationTracking} for different values.
*
* @param myLocationTrackingMode The location tracking mode to be used.
* @throws SecurityException if no suitable permission is present
* @see MyLocationTracking
*/
@UiThread
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
myLocationView.setLocationChangeAnimationEnabled(isLocationChangeAnimationEnabled());
myLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
zoomInvalidator.zoomTo(2.0);
focalPointChangedListener.onFocalPointChanged(myLocationView.getCenter());
} else {
focalPointChangedListener.onFocalPointChanged(null);
}
if (onMyLocationTrackingModeChangeListener != null) {
onMyLocationTrackingModeChangeListener.onMyLocationTrackingModeChange(myLocationTrackingMode);
}
}
/**
* Returns the current user location tracking mode.
*
* @return The current user location tracking mode.
* One of the values from {@link MyLocationTracking.Mode}.
* @see MyLocationTracking.Mode
*/
@UiThread
@MyLocationTracking.Mode
public int getMyLocationTrackingMode() {
return myLocationView.getMyLocationTrackingMode();
}
/**
* <p>
* Set the current my bearing tracking mode.
* </p>
* Shows the direction the user is heading.
* <p>
* When location tracking is disabled the direction of {@link MyLocationView} is rotated. When
* location tracking is enabled the {@link MapView} is rotated based on the bearing value.
* </p>
* See {@link MyBearingTracking} for different values.
*
* @param myBearingTrackingMode The bearing tracking mode to be used.
* @throws SecurityException if no suitable permission is present
* @see MyBearingTracking
*/
@UiThread
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
myLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
if (onMyBearingTrackingModeChangeListener != null) {
onMyBearingTrackingModeChangeListener.onMyBearingTrackingModeChange(myBearingTrackingMode);
}
}
/**
* Returns the current user bearing tracking mode.
* See {@link MyBearingTracking} for possible return values.
*
* @return the current user bearing tracking mode.
* @see MyBearingTracking
*/
@UiThread
@MyBearingTracking.Mode
public int getMyBearingTrackingMode() {
return myLocationView.getMyBearingTrackingMode();
}
/**
* Returns if all tracking modes will be dismissed when a gesture occurs.
*
* @return True to indicate that location and bearing tracking will be dismissed.
*/
public boolean isAllDismissTrackingOnGesture() {
return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
}
/**
* Set the dismissal of the tracking modes if a gesture occurs.
*
* @param dismissTrackingOnGesture True to dismiss all the tracking modes.
*/
public void setDismissAllTrackingOnGesture(boolean dismissTrackingOnGesture) {
dismissLocationTrackingOnGesture = dismissTrackingOnGesture;
dismissBearingTrackingOnGesture = dismissTrackingOnGesture;
}
/**
* Set the dismissal of the tracking modes if a gesture occurs.
*
* @param dismissLocationTrackingOnGesture True to dismiss the location tracking mode.
*/
public void setDismissLocationTrackingOnGesture(boolean dismissLocationTrackingOnGesture) {
this.dismissLocationTrackingOnGesture = dismissLocationTrackingOnGesture;
}
/**
* Returns if the location tracking will be disabled when a gesture occurs
*
* @return True if location tracking will be disabled.
*/
public boolean isDismissLocationTrackingOnGesture() {
return dismissLocationTrackingOnGesture;
}
/**
* Set the dismissal of the bearing tracking modes if a gesture occurs.
*
* @param dismissBearingTrackingOnGesture True to dimsiss the bearinf tracking mode
*/
public void setDismissBearingTrackingOnGesture(boolean dismissBearingTrackingOnGesture) {
this.dismissBearingTrackingOnGesture = dismissBearingTrackingOnGesture;
}
/**
* Returns if bearing will disabled when a gesture occurs
*
* @return True if bearing tracking will be disabled
*/
public boolean isDismissBearingTrackingOnGesture() {
return dismissBearingTrackingOnGesture;
}
/**
* Returns if location tracking is disabled
*
* @return True if location tracking is disabled.
*/
public boolean isLocationTrackingDisabled() {
return myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE;
}
/**
* Returns if bearing tracking disabled
*
* @return True if bearing tracking is disabled.
*/
public boolean isBearingTrackingDisabled() {
return myLocationView.getMyBearingTrackingMode() == MyBearingTracking.NONE;
}
/**
* Returns if rotate gesture are currently enabled.
*
* @return True if rotate gestures are currently enabled.
*/
public boolean isRotateGestureCurrentlyEnabled() {
// rotate gestures are recognised if:
// The user settings are enabled AND;
// EITHER bearing tracking is dismissed on gesture OR there is no bearing tracking
return uiSettings.isRotateGesturesEnabled()
&& (dismissBearingTrackingOnGesture
|| myLocationView.getMyBearingTrackingMode() == MyBearingTracking.NONE
|| myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE);
}
/**
* Returns if scroll gesture are currently enabled.
*
* @return True if scroll gestures are currently enabled.
*/
public boolean isScrollGestureCurrentlyEnabled() {
return uiSettings.isScrollGesturesEnabled()
&& (dismissLocationTrackingOnGesture
|| myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE);
}
/**
* Returns whether location change animation is applied for {@link MyLocationTracking#TRACKING_FOLLOW}.
*
* @return True if animation is applied, false otherwise.
*/
public boolean isLocationChangeAnimationEnabled() {
return locationChangeAnimationEnabled;
}
/**
* Set whether location change animation should be applied for {@link MyLocationTracking#TRACKING_FOLLOW}.
*
* @param locationChangeAnimationEnabled True if animation should be applied, false otherwise.
*/
public void setLocationChangeAnimationEnabled(boolean locationChangeAnimationEnabled) {
this.locationChangeAnimationEnabled = locationChangeAnimationEnabled;
myLocationView.setLocationChangeAnimationEnabled(locationChangeAnimationEnabled);
}
/**
* Reset the tracking modes as necessary. Location tracking is reset if the map center is changed and not from
* location, bearing tracking if there is a rotation.
*
* @param translate true if translation
* @param rotate true if rotation
* @param isFromLocation true if from location
*/
void resetTrackingModesIfRequired(boolean translate, boolean rotate, boolean isFromLocation) {
// if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture() && !isFromLocation) {
setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
}
// reset bearing tracking only on rotate
if (rotate && !isBearingTrackingDisabled() && isDismissBearingTrackingOnGesture()) {
setMyBearingTrackingMode(MyBearingTracking.NONE);
}
}
/**
* Reset the tracking modes as necessary. Animated camera position changes can reset the underlying tracking modes.
*
* @param currentCameraPosition the current camera position
* @param targetCameraPosition the changed camera position
* @param isFromLocation true if from location
*/
void resetTrackingModesIfRequired(CameraPosition currentCameraPosition, CameraPosition targetCameraPosition,
boolean isFromLocation) {
if (currentCameraPosition.target != null) {
resetTrackingModesIfRequired(!currentCameraPosition.target.equals(targetCameraPosition.target), false,
isFromLocation);
}
}
Location getMyLocation() {
return myLocationView.getLocation();
}
void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
if (listener != null) {
myLocationListener = new LocationEngineListener() {
@Override
public void onConnected() {
// Nothing
}
@Override
public void onLocationChanged(Location location) {
if (listener != null) {
listener.onMyLocationChange(location);
}
}
};
locationSource.addLocationEngineListener(myLocationListener);
} else {
locationSource.removeLocationEngineListener(myLocationListener);
myLocationListener = null;
}
}
public boolean isCustomLocationSource() {
return isCustomLocationSource;
}
void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
this.onMyLocationTrackingModeChangeListener = listener;
}
void setOnMyBearingTrackingModeChangeListener(MapboxMap.OnMyBearingTrackingModeChangeListener listener) {
this.onMyBearingTrackingModeChangeListener = listener;
}
MyLocationView getMyLocationView() {
return myLocationView;
}
boolean isMyLocationEnabled() {
return myLocationEnabled;
}
void setMyLocationEnabled(boolean locationEnabled) {
setMyLocationEnabled(locationEnabled, isCustomLocationSource());
}
private void setMyLocationEnabled(boolean locationEnabled, boolean isCustomLocationSource) {
if (locationEnabled && !PermissionsManager.areLocationPermissionsGranted(myLocationView.getContext())) {
Timber.e("Could not activate user location tracking: "
+ "user did not accept the permission or permissions were not requested.");
return;
}
myLocationEnabled = locationEnabled;
this.isCustomLocationSource = isCustomLocationSource;
myLocationView.setEnabled(locationEnabled, isCustomLocationSource);
}
void setLocationSource(LocationEngine locationSource) {
if (this.locationSource != null && this.locationSource.equals(locationSource)) {
// this source is already active
return;
}
this.isCustomLocationSource = locationSource != null;
if (locationSource == null) {
locationSource = Mapbox.getLocationEngine();
}
this.locationSource = locationSource;
myLocationView.setLocationSource(locationSource);
}
void update() {
if (!myLocationView.isEnabled()) {
return;
}
myLocationView.update();
}
void onStart() {
myLocationView.onStart();
}
void onStop() {
myLocationView.onStop();
}
interface CameraZoomInvalidator {
void zoomTo(double zoomLevel);
}
}

View File

@@ -12,7 +12,6 @@ import com.mapbox.mapboxsdk.camera.CameraUpdate;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import timber.log.Timber;
@@ -30,8 +29,6 @@ final class Transform implements MapView.OnMapChangedListener {
private final NativeMapView mapView;
private final MarkerViewManager markerViewManager;
private final TrackingSettings trackingSettings;
private final MyLocationView myLocationView;
private final Handler handler = new Handler();
private CameraPosition cameraPosition;
@@ -41,12 +38,10 @@ final class Transform implements MapView.OnMapChangedListener {
private CameraChangeDispatcher cameraChangeDispatcher;
Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings,
Transform(NativeMapView mapView, MarkerViewManager markerViewManager,
CameraChangeDispatcher cameraChangeDispatcher) {
this.mapView = mapView;
this.markerViewManager = markerViewManager;
this.trackingSettings = trackingSettings;
this.myLocationView = trackingSettings.getMyLocationView();
this.cameraChangeDispatcher = cameraChangeDispatcher;
}
@@ -73,9 +68,6 @@ final class Transform implements MapView.OnMapChangedListener {
@UiThread
void updateCameraPosition(@NonNull CameraPosition position) {
if (myLocationView != null) {
myLocationView.setCameraPosition(position);
}
markerViewManager.setTilt((float) position.tilt);
}
@@ -103,7 +95,6 @@ final class Transform implements MapView.OnMapChangedListener {
final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, final MapboxMap.CancelableCallback callback) {
CameraPosition cameraPosition = update.getCameraPosition(mapboxMap);
if (isValidCameraPosition(cameraPosition)) {
trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false);
cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION);
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
@@ -125,7 +116,6 @@ final class Transform implements MapView.OnMapChangedListener {
final MapboxMap.CancelableCallback callback, boolean isDismissable) {
CameraPosition cameraPosition = update.getCameraPosition(mapboxMap);
if (isValidCameraPosition(cameraPosition)) {
trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, isDismissable);
cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION);
@@ -143,7 +133,6 @@ final class Transform implements MapView.OnMapChangedListener {
final MapboxMap.CancelableCallback callback) {
CameraPosition cameraPosition = update.getCameraPosition(mapboxMap);
if (isValidCameraPosition(cameraPosition)) {
trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false);
cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION);
@@ -237,31 +226,15 @@ final class Transform implements MapView.OnMapChangedListener {
return mapView.getZoom();
}
void zoomIn(@NonNull PointF focalPoint) {
CameraPosition cameraPosition = invalidateCameraPosition();
if (cameraPosition != null) {
int newZoom = (int) Math.round(cameraPosition.zoom + 1);
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
}
}
void zoomOut(@NonNull PointF focalPoint) {
CameraPosition cameraPosition = invalidateCameraPosition();
if (cameraPosition != null) {
int newZoom = (int) Math.round(cameraPosition.zoom - 1);
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
}
}
void zoomBy(double zoomAddition, @NonNull PointF focalPoint) {
setZoom(mapView.getZoom() + zoomAddition, focalPoint, 0);
setZoom(mapView.getZoom() + zoomAddition, focalPoint);
}
void setZoom(double zoom, @NonNull PointF focalPoint) {
setZoom(zoom, focalPoint, 0);
}
void setZoom(double zoom, @NonNull PointF focalPoint, long duration) {
void setZoom(double zoom, @NonNull PointF focalPoint, final long duration) {
if (mapView != null) {
mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
@@ -297,23 +270,14 @@ final class Transform implements MapView.OnMapChangedListener {
}
void setBearing(double bearing) {
if (myLocationView != null) {
myLocationView.setBearing(bearing);
}
mapView.setBearing(bearing);
}
void setBearing(double bearing, float focalX, float focalY) {
if (myLocationView != null) {
myLocationView.setBearing(bearing);
}
mapView.setBearing(bearing, focalX, focalY);
}
void setBearing(double bearing, float focalX, float focalY, long duration) {
if (myLocationView != null) {
myLocationView.setBearing(bearing);
}
mapView.setBearing(bearing, focalX, focalY, duration);
}
@@ -335,9 +299,6 @@ final class Transform implements MapView.OnMapChangedListener {
}
void setTilt(Double pitch) {
if (myLocationView != null) {
myLocationView.setTilt(pitch);
}
markerViewManager.setTilt(pitch.floatValue());
mapView.setPitch(pitch, 0);
}

View File

@@ -45,21 +45,23 @@ public final class UiSettings {
private float pixelRatio;
private boolean rotateGesturesEnabled = true;
private boolean rotateGestureChangeAllowed = true;
private boolean tiltGesturesEnabled = true;
private boolean tiltGestureChangeAllowed = true;
private boolean zoomGesturesEnabled = true;
private boolean zoomGestureChangeAllowed = true;
private boolean scrollGesturesEnabled = true;
private boolean scrollGestureChangeAllowed = true;
private boolean zoomControlsEnabled;
private boolean doubleTapGesturesEnabled = true;
private boolean doubleTapGestureChangeAllowed = true;
private boolean scaleVelocityAnimationEnabled = true;
private boolean rotateVelocityAnimationEnabled = true;
private boolean flingVelocityAnimationEnabled = true;
private boolean increaseRotateThresholdWhenScaling = true;
private boolean increaseScaleThresholdWhenRotating = true;
private boolean deselectMarkersOnTap = true;
@@ -108,42 +110,39 @@ public final class UiSettings {
private void initialiseGestures(MapboxMapOptions options) {
setZoomGesturesEnabled(options.getZoomGesturesEnabled());
setZoomGestureChangeAllowed(options.getZoomGesturesEnabled());
setScrollGesturesEnabled(options.getScrollGesturesEnabled());
setScrollGestureChangeAllowed(options.getScrollGesturesEnabled());
setRotateGesturesEnabled(options.getRotateGesturesEnabled());
setRotateGestureChangeAllowed(options.getRotateGesturesEnabled());
setTiltGesturesEnabled(options.getTiltGesturesEnabled());
setTiltGestureChangeAllowed(options.getTiltGesturesEnabled());
setZoomControlsEnabled(options.getZoomControlsEnabled());
setDoubleTapGesturesEnabled(options.getDoubleTapGesturesEnabled());
setDoubleTapGestureChangeAllowed(options.getDoubleTapGesturesEnabled());
}
private void saveGestures(Bundle outState) {
outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED, isZoomGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE, isZoomGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, isScrollGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE, isScrollGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, isRotateGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, isRotateGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, isTiltGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, isTiltGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED, isDoubleTapGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED_CHANGE, isDoubleTapGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_SCALE_ANIMATION_ENABLED, isScaleVelocityAnimationEnabled());
outState.putBoolean(MapboxConstants.STATE_ROTATE_ANIMATION_ENABLED, isRotateVelocityAnimationEnabled());
outState.putBoolean(MapboxConstants.STATE_FLING_ANIMATION_ENABLED, isFlingVelocityAnimationEnabled());
outState.putBoolean(MapboxConstants.STATE_INCREASE_ROTATE_THRESHOLD, isIncreaseRotateThresholdWhenScaling());
outState.putBoolean(MapboxConstants.STATE_INCREASE_SCALE_THRESHOLD, isIncreaseScaleThresholdWhenRotating());
}
private void restoreGestures(Bundle savedInstanceState) {
setZoomGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED));
setZoomGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE));
setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED));
setScrollGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE));
setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED));
setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE));
setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED));
setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE));
setDoubleTapGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED));
setDoubleTapGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED_CHANGE));
setScaleVelocityAnimationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCALE_ANIMATION_ENABLED));
setRotateVelocityAnimationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ANIMATION_ENABLED));
setFlingVelocityAnimationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_FLING_ANIMATION_ENABLED));
setIncreaseRotateThresholdWhenScaling(
savedInstanceState.getBoolean(MapboxConstants.STATE_INCREASE_ROTATE_THRESHOLD));
setIncreaseScaleThresholdWhenRotating(
savedInstanceState.getBoolean(MapboxConstants.STATE_INCREASE_SCALE_THRESHOLD));
}
private void initialiseCompass(MapboxMapOptions options, Resources resources) {
@@ -658,9 +657,7 @@ public final class UiSettings {
* @param rotateGesturesEnabled If true, rotating is enabled.
*/
public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) {
if (rotateGestureChangeAllowed) {
this.rotateGesturesEnabled = rotateGesturesEnabled;
}
this.rotateGesturesEnabled = rotateGesturesEnabled;
}
/**
@@ -672,14 +669,6 @@ public final class UiSettings {
return rotateGesturesEnabled;
}
void setRotateGestureChangeAllowed(boolean rotateGestureChangeAllowed) {
this.rotateGestureChangeAllowed = rotateGestureChangeAllowed;
}
boolean isRotateGestureChangeAllowed() {
return rotateGestureChangeAllowed;
}
/**
* <p>
* Changes whether the user may tilt the map.
@@ -693,9 +682,8 @@ public final class UiSettings {
* @param tiltGesturesEnabled If true, tilting is enabled.
*/
public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) {
if (tiltGestureChangeAllowed) {
this.tiltGesturesEnabled = tiltGesturesEnabled;
}
this.tiltGesturesEnabled = tiltGesturesEnabled;
}
/**
@@ -707,14 +695,6 @@ public final class UiSettings {
return tiltGesturesEnabled;
}
void setTiltGestureChangeAllowed(boolean tiltGestureChangeAllowed) {
this.tiltGestureChangeAllowed = tiltGestureChangeAllowed;
}
boolean isTiltGestureChangeAllowed() {
return tiltGestureChangeAllowed;
}
/**
* <p>
* Changes whether the user may zoom the map.
@@ -728,9 +708,7 @@ public final class UiSettings {
* @param zoomGesturesEnabled If true, zooming is enabled.
*/
public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
if (zoomGestureChangeAllowed) {
this.zoomGesturesEnabled = zoomGesturesEnabled;
}
this.zoomGesturesEnabled = zoomGesturesEnabled;
}
/**
@@ -742,14 +720,6 @@ public final class UiSettings {
return zoomGesturesEnabled;
}
void setZoomGestureChangeAllowed(boolean zoomGestureChangeAllowed) {
this.zoomGestureChangeAllowed = zoomGestureChangeAllowed;
}
boolean isZoomGestureChangeAllowed() {
return zoomGestureChangeAllowed;
}
/**
* <p>
* Sets whether the zoom controls are enabled.
@@ -788,9 +758,7 @@ public final class UiSettings {
* @param doubleTapGesturesEnabled If true, zooming with a double tap is enabled.
*/
public void setDoubleTapGesturesEnabled(boolean doubleTapGesturesEnabled) {
if (doubleTapGestureChangeAllowed) {
this.doubleTapGesturesEnabled = doubleTapGesturesEnabled;
}
this.doubleTapGesturesEnabled = doubleTapGesturesEnabled;
}
/**
@@ -802,14 +770,6 @@ public final class UiSettings {
return doubleTapGesturesEnabled;
}
void setDoubleTapGestureChangeAllowed(boolean doubleTapGestureChangeAllowed) {
this.doubleTapGestureChangeAllowed = doubleTapGestureChangeAllowed;
}
boolean isDoubleTapGestureChangeAllowed() {
return doubleTapGestureChangeAllowed;
}
private void restoreDeselectMarkersOnTap(Bundle savedInstanceState) {
setDeselectMarkersOnTap(savedInstanceState.getBoolean(MapboxConstants.STATE_DESELECT_MARKER_ON_TAP));
}
@@ -851,9 +811,7 @@ public final class UiSettings {
* @param scrollGesturesEnabled If true, scrolling is enabled.
*/
public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) {
if (scrollGestureChangeAllowed) {
this.scrollGesturesEnabled = scrollGesturesEnabled;
}
this.scrollGesturesEnabled = scrollGesturesEnabled;
}
/**
@@ -865,12 +823,105 @@ public final class UiSettings {
return scrollGesturesEnabled;
}
void setScrollGestureChangeAllowed(boolean scrollGestureChangeAllowed) {
this.scrollGestureChangeAllowed = scrollGestureChangeAllowed;
/**
* Returns whether scale velocity animation should execute after users finishes a gesture.
*
* @return If true, scale velocity animation is enabled.
*/
public boolean isScaleVelocityAnimationEnabled() {
return scaleVelocityAnimationEnabled;
}
boolean isScrollGestureChangeAllowed() {
return scrollGestureChangeAllowed;
/**
* Set whether scale velocity animation should execute after users finishes a gesture. True by default.
*
* @param scaleVelocityAnimationEnabled If true, scale velocity animation will be enabled.
*/
public void setScaleVelocityAnimationEnabled(boolean scaleVelocityAnimationEnabled) {
this.scaleVelocityAnimationEnabled = scaleVelocityAnimationEnabled;
}
/**
* Returns whether rotate velocity animation should execute after users finishes a gesture.
*
* @return If true, rotate velocity animation is enabled.
*/
public boolean isRotateVelocityAnimationEnabled() {
return rotateVelocityAnimationEnabled;
}
/**
* Set whether rotate velocity animation should execute after users finishes a gesture. True by default.
*
* @param rotateVelocityAnimationEnabled If true, rotate velocity animation will be enabled.
*/
public void setRotateVelocityAnimationEnabled(boolean rotateVelocityAnimationEnabled) {
this.rotateVelocityAnimationEnabled = rotateVelocityAnimationEnabled;
}
/**
* Returns whether fling velocity animation should execute after users finishes a gesture.
*
* @return If true, fling velocity animation is enabled.
*/
public boolean isFlingVelocityAnimationEnabled() {
return flingVelocityAnimationEnabled;
}
/**
* Set whether fling velocity animation should execute after users finishes a gesture. True by default.
*
* @param flingVelocityAnimationEnabled If true, fling velocity animation will be enabled.
*/
public void setFlingVelocityAnimationEnabled(boolean flingVelocityAnimationEnabled) {
this.flingVelocityAnimationEnabled = flingVelocityAnimationEnabled;
}
/**
* Set whether all velocity animations should execute after users finishes a gesture.
*
* @param allVelocityAnimationsEnabled If true, all velocity animations will be enabled.
*/
public void setAllVelocityAnimationsEnabled(boolean allVelocityAnimationsEnabled) {
setScaleVelocityAnimationEnabled(allVelocityAnimationsEnabled);
setRotateVelocityAnimationEnabled(allVelocityAnimationsEnabled);
setFlingVelocityAnimationEnabled(allVelocityAnimationsEnabled);
}
/**
* Returns whether rotation threshold should be increase whenever scale is detected.
*
* @return If true, rotation threshold will be increased.
*/
public boolean isIncreaseRotateThresholdWhenScaling() {
return increaseRotateThresholdWhenScaling;
}
/**
* Set whether rotation threshold should be increase whenever scale is detected.
*
* @param increaseRotateThresholdWhenScaling If true, rotation threshold will be increased.
*/
public void setIncreaseRotateThresholdWhenScaling(boolean increaseRotateThresholdWhenScaling) {
this.increaseRotateThresholdWhenScaling = increaseRotateThresholdWhenScaling;
}
/**
* Returns whether scale threshold should be increase whenever rotation is detected.
*
* @return If true, scale threshold will be increased.
*/
public boolean isIncreaseScaleThresholdWhenRotating() {
return increaseScaleThresholdWhenRotating;
}
/**
* set whether scale threshold should be increase whenever rotation is detected.
*
* @param increaseScaleThresholdWhenRotating If true, scale threshold will be increased.
*/
public void setIncreaseScaleThresholdWhenRotating(boolean increaseScaleThresholdWhenRotating) {
this.increaseScaleThresholdWhenRotating = increaseScaleThresholdWhenRotating;
}
/**

View File

@@ -37,11 +37,11 @@ public abstract class MapRenderer implements MapRendererScheduler {
}
public void onPause() {
// Implement if needed
nativeOnPause();
}
public void onResume() {
// Implement if needed
nativeOnResume();
}
public void onStop() {
@@ -124,6 +124,10 @@ public abstract class MapRenderer implements MapRendererScheduler {
private native void nativeRender();
private native void nativeOnResume();
private native void nativeOnPause();
private long frames;
private long timeElapsed;

View File

@@ -54,6 +54,17 @@ public class EGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
@SuppressWarnings("JavadocReference")
private static final int EGL_OPENGL_ES2_BIT = 0x0004;
private boolean translucentSurface;
public EGLConfigChooser() {
this(false);
}
public EGLConfigChooser(boolean translucentSurface) {
super();
this.translucentSurface = translucentSurface;
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] configAttribs = getConfigAttributes();
@@ -274,7 +285,7 @@ public class EGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_ALPHA_SIZE, translucentSurface ? 8 : 0,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 8,
(emulator ? EGL_NONE : EGL_CONFORMANT), EGL_OPENGL_ES2_BIT,

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android EGL API classes.
*/
package com.mapbox.mapboxsdk.maps.renderer.egl;

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android GLSurfaceView API classes.
*/
package com.mapbox.mapboxsdk.maps.renderer.glsurfaceview;

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android Renderer API classes.
*/
package com.mapbox.mapboxsdk.maps.renderer;

View File

@@ -17,17 +17,22 @@ import javax.microedition.khronos.opengles.GL10;
*/
public class TextureViewMapRenderer extends MapRenderer {
private TextureViewRenderThread renderThread;
private boolean translucentSurface;
/**
* Create a {@link MapRenderer} for the given {@link TextureView}
*
* @param context the current Context
* @param textureView the TextureView
* @param context the current Context
* @param textureView the TextureView
* @param localIdeographFontFamily the local font family
* @param translucentSurface the translucency flag
*/
public TextureViewMapRenderer(@NonNull Context context,
@NonNull TextureView textureView,
String localIdeographFontFamily) {
String localIdeographFontFamily,
boolean translucentSurface) {
super(context, localIdeographFontFamily);
this.translucentSurface = translucentSurface;
renderThread = new TextureViewRenderThread(textureView, this);
renderThread.start();
}
@@ -95,4 +100,8 @@ public class TextureViewMapRenderer extends MapRenderer {
public void onDestroy() {
renderThread.onDestroy();
}
public boolean isTranslucentSurface() {
return translucentSurface;
}
}

View File

@@ -53,9 +53,10 @@ class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextu
*/
@UiThread
TextureViewRenderThread(@NonNull TextureView textureView, @NonNull TextureViewMapRenderer mapRenderer) {
textureView.setOpaque(!mapRenderer.isTranslucentSurface());
textureView.setSurfaceTextureListener(this);
this.mapRenderer = mapRenderer;
this.eglHolder = new EGLHolder(new WeakReference<>(textureView));
this.eglHolder = new EGLHolder(new WeakReference<>(textureView), mapRenderer.isTranslucentSurface());
}
// SurfaceTextureListener methods
@@ -324,6 +325,7 @@ class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextu
private static class EGLHolder {
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private final WeakReference<TextureView> textureViewWeakRef;
private boolean translucentSurface;
private EGL10 egl;
private EGLConfig eglConfig;
@@ -331,8 +333,9 @@ class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextu
private EGLContext eglContext = EGL10.EGL_NO_CONTEXT;
private EGLSurface eglSurface = EGL10.EGL_NO_SURFACE;
EGLHolder(WeakReference<TextureView> textureViewWeakRef) {
EGLHolder(WeakReference<TextureView> textureViewWeakRef, boolean translucentSurface) {
this.textureViewWeakRef = textureViewWeakRef;
this.translucentSurface = translucentSurface;
}
void prepare() {
@@ -357,7 +360,7 @@ class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextu
eglConfig = null;
eglContext = EGL10.EGL_NO_CONTEXT;
} else if (eglContext == EGL10.EGL_NO_CONTEXT) {
eglConfig = new EGLConfigChooser().chooseConfig(egl, eglDisplay);
eglConfig = new EGLConfigChooser(translucentSurface).chooseConfig(egl, eglDisplay);
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
eglContext = egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
}

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android TextureView API classes.
*/
package com.mapbox.mapboxsdk.maps.renderer.textureview;

View File

@@ -1,15 +1,16 @@
package com.mapbox.mapboxsdk.maps.widgets;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorCompat;
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -22,7 +23,8 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
* use {@link com.mapbox.mapboxsdk.maps.UiSettings}.
* </p>
*/
public final class CompassView extends AppCompatImageView implements Runnable {
@SuppressLint("AppCompatCustomView")
public final class CompassView extends ImageView implements Runnable {
public static final long TIME_WAIT_IDLE = 500;
public static final long TIME_MAP_NORTH_ANIMATION = 150;

View File

@@ -1,389 +0,0 @@
package com.mapbox.mapboxsdk.maps.widgets;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.maps.FocalPointChangeListener;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
/**
* Settings to configure the visual appearance of the MyLocationView.
*
* @deprecated use location layer plugin from
* https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
@Deprecated
public class MyLocationViewSettings {
private Projection projection;
private MyLocationView myLocationView;
private FocalPointChangeListener focalPointChangeListener;
//
// State
//
private boolean enabled;
//
// Foreground
//
private Drawable foregroundDrawable;
private Drawable foregroundBearingDrawable;
@ColorInt
private int foregroundTintColor;
//
// Background
//
private Drawable backgroundDrawable;
private int[] backgroundOffset = new int[4];
@ColorInt
private int backgroundTintColor;
//
// Accuracy
//
private int accuracyAlpha;
private float accuracyThreshold = 0f;
@ColorInt
private int accuracyTintColor;
//
// Padding
//
private int[] padding = new int[4];
/**
* Creates an instance of MyLocationViewSettings
* <p>
*
* @param myLocationView the MyLocationView to apply the settings to
* @param projection the MapView projection
* @param focalPointChangedListener the interface to be invoked when focal points changes
* @see MyLocationView
*/
public MyLocationViewSettings(MyLocationView myLocationView, Projection projection, FocalPointChangeListener
focalPointChangedListener) {
this.myLocationView = myLocationView;
this.projection = projection;
this.focalPointChangeListener = focalPointChangedListener;
}
/**
* Initialise this with MapboxMapOptions.
*
* @param options the options to initialise this class from
*/
public void initialise(@NonNull MapboxMapOptions options) {
CameraPosition position = options.getCamera();
if (position != null && !position.equals(CameraPosition.DEFAULT)) {
setTilt(position.tilt);
}
setForegroundDrawable(options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
setForegroundTintColor(options.getMyLocationForegroundTintColor());
setBackgroundDrawable(options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
setBackgroundTintColor(options.getMyLocationBackgroundTintColor());
setAccuracyAlpha(options.getMyLocationAccuracyAlpha());
setAccuracyTintColor(options.getMyLocationAccuracyTintColor());
setAccuracyThreshold(options.getMyLocationAccuracyThreshold());
}
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(MapboxConstants.STATE_LOCATION_VIEW_ENABLED, isEnabled());
outState.putByteArray(
MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_DRAWABLE,
BitmapUtils.getByteArrayFromDrawable(getForegroundDrawable())
);
outState.putByteArray(
MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_BEARING_DRAWABLE,
BitmapUtils.getByteArrayFromDrawable(getForegroundBearingDrawable())
);
outState.putInt(MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_TINT_COLOR, getForegroundTintColor());
outState.putByteArray(
MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_DRAWABLE,
BitmapUtils.getByteArrayFromDrawable(getBackgroundDrawable())
);
outState.putIntArray(MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_OFFSET, getBackgroundOffset());
outState.putInt(MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_TINT_COLOR, getBackgroundTintColor());
outState.putInt(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_ALPHA, getAccuracyAlpha());
outState.putInt(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_TINT_COLOR, getAccuracyTintColor());
outState.putFloat(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_THRESHOLD, getAccuracyThreshold());
outState.putIntArray(MapboxConstants.STATE_LOCATION_VIEW_PADDING, getPadding());
}
public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
setEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOCATION_VIEW_ENABLED));
setForegroundDrawable(
BitmapUtils.getDrawableFromByteArray(
myLocationView.getContext(),
savedInstanceState.getByteArray(MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_DRAWABLE)
),
BitmapUtils.getDrawableFromByteArray(
myLocationView.getContext(),
savedInstanceState.getByteArray(MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_BEARING_DRAWABLE)
)
);
setForegroundTintColor(savedInstanceState.getInt(MapboxConstants.STATE_LOCATION_VIEW_FOREGROUND_TINT_COLOR));
setBackgroundDrawable(
BitmapUtils.getDrawableFromByteArray(
myLocationView.getContext(),
savedInstanceState.getByteArray(MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_DRAWABLE)
),
savedInstanceState.getIntArray(MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_OFFSET)
);
setBackgroundTintColor(savedInstanceState.getInt(MapboxConstants.STATE_LOCATION_VIEW_BACKGROUND_TINT_COLOR));
setAccuracyAlpha(savedInstanceState.getInt(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_ALPHA));
setAccuracyTintColor(savedInstanceState.getInt(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_TINT_COLOR));
setAccuracyThreshold(savedInstanceState.getFloat(MapboxConstants.STATE_LOCATION_VIEW_ACCURACY_THRESHOLD));
setPadding(savedInstanceState.getIntArray(MapboxConstants.STATE_LOCATION_VIEW_PADDING));
}
/**
* Returns if the MyLocationView is enabled
*
* @return true if MyLocationView is enabled,
*/
public boolean isEnabled() {
return enabled;
}
/**
* Set the enabled state of MyLocationView
*
* @param enabled true shows the MyLocationView on the map
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
myLocationView.setEnabled(enabled);
}
/**
* Set the foreground drawable of the MyLocationView
* <p>
* The foreground drawable is the image visible on screen
* </p>
* It's linked with the foreground tint color
*
* @param foregroundDrawable the drawable to show as foreground without bearing
* @param foregroundBearingDrawable the drawable to show as foreground when bearing is enabled
*/
public void setForegroundDrawable(Drawable foregroundDrawable, Drawable foregroundBearingDrawable) {
this.foregroundDrawable = foregroundDrawable;
this.foregroundBearingDrawable = foregroundBearingDrawable;
myLocationView.setForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
myLocationView.setForegroundDrawableTint(foregroundTintColor);
}
/**
* Get the foreground drawable when bearing is disabled.
*
* @return the drawable used as foreground
*/
public Drawable getForegroundDrawable() {
return foregroundDrawable;
}
/**
* Get the foreground drawable when bearing is enabled.
*
* @return the bearing drawable used as foreground
*/
public Drawable getForegroundBearingDrawable() {
return foregroundBearingDrawable;
}
/**
* Set the foreground tint color.
* <p>
* The color will tint both the foreground and the bearing foreground drawable.
* </p>
*
* @param foregroundTintColor the color to tint the foreground drawable or -1 (undefined color) to remove the
* existing foreground tint color
*/
public void setForegroundTintColor(@ColorInt int foregroundTintColor) {
this.foregroundTintColor = foregroundTintColor;
myLocationView.setForegroundDrawableTint(foregroundTintColor);
}
/**
* Get the foreground tint color.
*
* @return the foreground tint color
*/
public int getForegroundTintColor() {
return foregroundTintColor;
}
/**
* Set the background drawable of MyLocationView
* <p>
* Padding can be added to provide an offset to the background
* </p>
* It's linked with the background tint color
*
* @param backgroundDrawable the drawable to show as background
* @param padding the padding added to the background
*/
public void setBackgroundDrawable(Drawable backgroundDrawable, int[] padding) {
this.backgroundDrawable = backgroundDrawable;
this.backgroundOffset = padding;
if (padding != null && padding.length == 4) {
myLocationView.setShadowDrawable(backgroundDrawable, padding[0], padding[1], padding[2], padding[3]);
} else {
myLocationView.setShadowDrawable(backgroundDrawable);
}
myLocationView.setShadowDrawableTint(backgroundTintColor);
}
/**
* Get the background drawable of MyLocationView.
*
* @return the drawable used as background
*/
public Drawable getBackgroundDrawable() {
return backgroundDrawable;
}
/**
* Set the background tint color.
*
* @param backgroundTintColor the color to tint the background drawable or -1 (undefined color) to remove the
* existing background tint color
*/
public void setBackgroundTintColor(@ColorInt int backgroundTintColor) {
this.backgroundTintColor = backgroundTintColor;
myLocationView.setShadowDrawableTint(backgroundTintColor);
}
/**
* Get the background tint color.
*
* @return the background tint color
*/
public int getBackgroundTintColor() {
return backgroundTintColor;
}
/**
* Get the background offset.
*
* @return the background offset
*/
public int[] getBackgroundOffset() {
return backgroundOffset;
}
/**
* Set the MyLocationView padding.
*
* @param left the padding left of MyLocationView
* @param top the padding top of MyLocationView
* @param right the padding right of MyLocationView
* @param bottom the padding bottom of MyLocaionView
*/
public void setPadding(int left, int top, int right, int bottom) {
padding = new int[] {left, top, right, bottom};
setPadding(padding);
}
private void setPadding(int[] padding) {
myLocationView.setContentPadding(padding);
projection.invalidateContentPadding(padding);
invalidateFocalPointForTracking(myLocationView);
}
/**
* Get the MyLocationView padding.
*
* @return an array describing the padding in a LTRB manner
*/
public int[] getPadding() {
return padding;
}
/**
* Get the alpha value of the accuracy circle of MyLocationView
*
* @return the alpha value
*/
public int getAccuracyAlpha() {
return accuracyAlpha;
}
/**
* Set the alpha value of the accuracy circle of MyLocationView
*
* @param accuracyAlpha the alpha value to set
*/
public void setAccuracyAlpha(@IntRange(from = 0, to = 255) int accuracyAlpha) {
this.accuracyAlpha = accuracyAlpha;
myLocationView.setAccuracyAlpha(accuracyAlpha);
}
/**
* Get the accuracy tint color of MyLocationView.
*
* @return the tint color used for accuracy
*/
public int getAccuracyTintColor() {
return accuracyTintColor;
}
/**
* Set the accuracy tint color of MyLocationView.
*
* @param accuracyTintColor the accuracy tint color
*/
public void setAccuracyTintColor(@ColorInt int accuracyTintColor) {
this.accuracyTintColor = accuracyTintColor;
myLocationView.setAccuracyTint(accuracyTintColor);
}
/**
* Returns current accuracy threshold value (in meters).
*
* @return Value of accuracy threshold (in meters), below which circle won't be displayed
*/
public float getAccuracyThreshold() {
return accuracyThreshold;
}
/**
* Set accuracy circle threshold. Circle won't be displayed if accuracy is below set value.
*
* @param accuracyThreshold Value of accuracy (in meters), below which circle won't be displayed
*/
public void setAccuracyThreshold(float accuracyThreshold) {
this.accuracyThreshold = accuracyThreshold;
myLocationView.setAccuracyThreshold(accuracyThreshold);
}
public void setTilt(double tilt) {
myLocationView.setTilt(tilt);
}
private void invalidateFocalPointForTracking(MyLocationView myLocationView) {
if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) {
focalPointChangeListener.onFocalPointChanged(myLocationView.getCenter());
} else {
focalPointChangeListener.onFocalPointChanged(null);
}
}
}

View File

@@ -5,7 +5,6 @@ import android.os.Looper;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.LibraryLoader;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.storage.FileSource;
@@ -250,9 +249,12 @@ public class OfflineRegion {
@Override
public void onStatusChanged(final OfflineRegionStatus status) {
if (deliverMessages()) {
handler.post(() -> {
if (observer != null) {
observer.onStatusChanged(status);
handler.post(new Runnable() {
@Override
public void run() {
if (observer != null) {
observer.onStatusChanged(status);
}
}
});
}
@@ -261,9 +263,12 @@ public class OfflineRegion {
@Override
public void onError(final OfflineRegionError error) {
if (deliverMessages()) {
handler.post(() -> {
if (observer != null) {
observer.onError(error);
handler.post(new Runnable() {
@Override
public void run() {
if (observer != null) {
observer.onError(error);
}
}
});
}
@@ -272,9 +277,12 @@ public class OfflineRegion {
@Override
public void mapboxTileCountLimitExceeded(final long limit) {
if (deliverMessages()) {
handler.post(() -> {
if (observer != null) {
observer.mapboxTileCountLimitExceeded(limit);
handler.post(new Runnable() {
@Override
public void run() {
if (observer != null) {
observer.mapboxTileCountLimitExceeded(limit);
}
}
});
}
@@ -313,17 +321,23 @@ public class OfflineRegion {
getOfflineRegionStatus(new OfflineRegionStatusCallback() {
@Override
public void onStatus(final OfflineRegionStatus status) {
handler.post(() -> {
callback.onStatus(status);
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
handler.post(new Runnable() {
@Override
public void run() {
callback.onStatus(status);
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
}
});
}
@Override
public void onError(final String error) {
handler.post(() -> {
callback.onError(error);
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
handler.post(new Runnable() {
@Override
public void run() {
callback.onError(error);
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
}
});
}
});
@@ -353,19 +367,25 @@ public class OfflineRegion {
deleteOfflineRegion(new OfflineRegionDeleteCallback() {
@Override
public void onDelete() {
handler.post((Runnable) () -> {
callback.onDelete();
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
OfflineRegion.this.finalize();
handler.post(new Runnable() {
@Override
public void run() {
callback.onDelete();
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
OfflineRegion.this.finalize();
}
});
}
@Override
public void onError(final String error) {
handler.post(() -> {
isDeleted = false;
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
callback.onError(error);
handler.post(new Runnable() {
@Override
public void run() {
isDeleted = false;
FileSource.getInstance(Mapbox.getApplicationContext()).deactivate();
callback.onError(error);
}
});
}
});
@@ -386,15 +406,23 @@ public class OfflineRegion {
updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() {
@Override
public void onUpdate(final byte[] metadata) {
handler.post(() -> {
OfflineRegion.this.metadata = metadata;
callback.onUpdate(metadata);
handler.post(new Runnable() {
@Override
public void run() {
OfflineRegion.this.metadata = metadata;
callback.onUpdate(metadata);
}
});
}
@Override
public void onError(final String error) {
handler.post(() -> callback.onError(error));
handler.post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}

View File

@@ -10,12 +10,12 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
* An offline region defined by a style URL, geographic bounding box, zoom range, and
* device pixel ratio.
* <p>
* Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
* Both minZoom and maxZoom must be &#x2265; 0, and maxZoom must be &#x2265; minZoom.
* <p>
* maxZoom may be ∞, in which case for each tile source, the region will include
* maxZoom may be &#x221E;, in which case for each tile source, the region will include
* tiles from minZoom up to the maximum zoom level provided by that source.
* <p>
* pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
* pixelRatio must be &#x2265; 0 and should typically be 1.0 or 2.0.
*/
public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefinition, Parcelable {

View File

@@ -82,7 +82,7 @@ public class MapSnapshotter {
* MapSnapshotter options
*/
public static class Options {
private int pixelRatio = 1;
private float pixelRatio = 1;
private int width;
private int height;
private String styleUrl = Style.MAPBOX_STREETS;
@@ -95,6 +95,9 @@ public class MapSnapshotter {
* @param height the height of the image
*/
public Options(int width, int height) {
if (width == 0 || height == 0) {
throw new IllegalArgumentException("Unable to create a snapshot with width or height set to 0");
}
this.width = width;
this.height = height;
}
@@ -122,7 +125,7 @@ public class MapSnapshotter {
* @param pixelRatio the pixel ratio to use (default: 1)
* @return the mutated {@link Options}
*/
public Options withPixelRatio(int pixelRatio) {
public Options withPixelRatio(float pixelRatio) {
this.pixelRatio = pixelRatio;
return this;
}
@@ -164,7 +167,7 @@ public class MapSnapshotter {
/**
* @return the pixel ratio
*/
public int getPixelRatio() {
public float getPixelRatio() {
return pixelRatio;
}

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android Snapshotter API classes.
*/
package com.mapbox.mapboxsdk.snapshotter;

View File

@@ -0,0 +1,4 @@
/**
* Contains the Mapbox Maps Android Expression API classes.
*/
package com.mapbox.mapboxsdk.style.expressions;

View File

@@ -1,50 +0,0 @@
package com.mapbox.mapboxsdk.style.functions;
import android.support.annotation.Keep;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops;
import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops;
import com.mapbox.mapboxsdk.style.functions.stops.Stop;
import com.mapbox.mapboxsdk.style.functions.stops.Stops;
/**
* Camera function. Functions that take camera properties as input (zoom for now)
* <p>
* Zoom functions allow the appearance of a map feature to change with map’s zoom level.
* Zoom functions can be used to create the illusion of depth and control data density.
* Each stop is an array with two elements: the first is a zoom level and the second is
* a function output value.
*
* @param <I> the input type
* @param <O> the output type
* @see Function#zoom
*/
public class CameraFunction<I extends Number, O> extends Function<I, O> {
/**
* Create an exponential camera function
*
* @param stops @see {@link com.mapbox.mapboxsdk.style.functions.stops.Stops#exponential(float, Stop[])}
*/
CameraFunction(@NonNull ExponentialStops<I, O> stops) {
super(stops);
}
/**
* Create an interval camera function
*
* @param stops @see {@link com.mapbox.mapboxsdk.style.functions.stops.Stops#interval(Stop[])}
*/
CameraFunction(@NonNull IntervalStops<I, O> stops) {
super(stops);
}
/**
* JNI constructor
*/
@Keep
private CameraFunction(Stops<I, O> stops) {
super(stops);
}
}

View File

@@ -1,100 +0,0 @@
package com.mapbox.mapboxsdk.style.functions;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops;
import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops;
import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops;
import com.mapbox.mapboxsdk.style.functions.stops.Stop;
import com.mapbox.mapboxsdk.style.functions.stops.Stops;
import com.mapbox.mapboxsdk.style.layers.PropertyValue;
import java.util.Map;
/**
* Composite functions combine Camera and SourceFunctions.
* <p>
* Composite functions allow the appearance of a map feature to change with both its
* properties and zoom. Each stop is an array with two elements, the first is an object
* with a property input value and a zoom, and the second is a function output value. Note
* that support for property functions is not yet complete.
*
* @param <Z> the zoom type (usually Float)
* @param <I> the input type (the feature property type)
* @param <O> the output type (the property type)
* @see Function#composite
*/
public class CompositeFunction<Z extends Number, I, O> extends Function<Stop.CompositeValue<Z, I>, O> {
private final String property;
private PropertyValue<O> defaultValue;
CompositeFunction(@NonNull String property,
@NonNull CategoricalStops<Stop.CompositeValue<Z, I>, O> stops) {
this(null, property, stops);
}
CompositeFunction(@NonNull String property,
@NonNull ExponentialStops<Stop.CompositeValue<Z, I>, O> stops) {
this(null, property, stops);
}
CompositeFunction(@NonNull String property,
@NonNull IntervalStops<Stop.CompositeValue<Z, I>, O> stops) {
this(null, property, stops);
}
/**
* JNI Constructor
*/
private CompositeFunction(@Nullable O defaultValue, @NonNull String property,
@NonNull Stops<Stop.CompositeValue<Z, I>, O> stops) {
super(stops);
this.defaultValue = new PropertyValue<>(property, defaultValue);
this.property = property;
}
/**
* Set the default value
*
* @param defaultValue the default value to use when no other applies
* @return this (for chaining)
*/
public CompositeFunction<Z, I, O> withDefaultValue(PropertyValue<O> defaultValue) {
this.defaultValue = defaultValue;
return this;
}
/**
* @return the defaultValue
*/
@Nullable
public PropertyValue<O> getDefaultValue() {
return defaultValue;
}
/**
* INTERNAL USAGE ONLY
*
* @return the feature property name
*/
public String getProperty() {
return property;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> toValueObject() {
Map<String, Object> valueObject = super.toValueObject();
valueObject.put(PROPERTY_KEY, property);
if (defaultValue != null) {
valueObject.put(DEFAULT_VALUE_KEY, defaultValue.value);
}
return valueObject;
}
}

View File

@@ -1,300 +0,0 @@
package com.mapbox.mapboxsdk.style.functions;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops;
import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops;
import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops;
import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops;
import com.mapbox.mapboxsdk.style.functions.stops.Stop;
import com.mapbox.mapboxsdk.style.functions.stops.Stops;
import java.util.Map;
import timber.log.Timber;
/**
* Functions are used to change properties in relation to the state of the map.
* <p>
* The value for any layout or paint property may be specified as a function. Functions allow you to
* make the appearance of a map feature change with the current zoom level and/or the feature's properties.
*
* @param <I> the function's input type
* @param <O> the target property's value type. Make sure it matches.
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
*/
public class Function<I, O> {
static final String PROPERTY_KEY = "property";
static final String DEFAULT_VALUE_KEY = "default";
/**
* Create an exponential {@link CameraFunction}
* <p>
* Zoom functions allow the appearance of a map feature to change with map’s zoom.
* Zoom functions can be used to create the illusion of depth and control data density.
* Each stop is an array with two elements, the first is a zoom and the second is a function output value.
*
* @param <Z> the zoom level type (Float, Integer)
* @param <O> the property type
* @param stops the stops implementation that define the function. @see {@link Stops#exponential(Stop[])}
* @return the {@link CameraFunction}
* @see CameraFunction
* @see ExponentialStops
* @see Stops#exponential(Stop[])
* @see Stops#exponential(Stop[])
* @see Stop#stop
*/
public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull ExponentialStops<Z, O> stops) {
return new CameraFunction<>(stops);
}
/**
* Create an interval {@link CameraFunction}
* <p>
* Zoom functions allow the appearance of a map feature to change with map’s zoom.
* Zoom functions can be used to create the illusion of depth and control data density.
* Each stop is an array with two elements, the first is a zoom and the second is a function output value.
*
* @param <Z> the zoom level type (Float, Integer)
* @param <O> the property type
* @param stops the stops implementation that define the function. @see {@link Stops#interval(Stop[])}
* @return the {@link CameraFunction}
* @see CameraFunction
* @see IntervalStops
* @see Stops#interval(Stop[])
* @see Stop#stop
*/
public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull IntervalStops<Z, O> stops) {
return new CameraFunction<>(stops);
}
/**
* Create an exponential {@link SourceFunction}
* <p>
* Source functions allow the appearance of a map feature to change with
* its properties. Source functions can be used to visually differentiate
* types of features within the same layer or create data visualizations.
* Each stop is an array with two elements, the first is a property input
* value and the second is a function output value. Note that support for
* property functions is not available across all properties and platforms
* at this time.
*
* @param property the feature property name
* @param stops the stops
* @param <I> the function input type
* @param <O> the function output type
* @return the {@link SourceFunction}
* @see SourceFunction
* @see ExponentialStops
* @see Stops#exponential(Stop[])
* @see Stop#stop
*/
public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull ExponentialStops<I, O> stops) {
return new SourceFunction<>(property, stops);
}
/**
* Create an identity {@link SourceFunction}
* <p>
* Source functions allow the appearance of a map feature to change with
* its properties. Source functions can be used to visually differentiate
* types of features within the same layer or create data visualizations.
* Each stop is an array with two elements, the first is a property input
* value and the second is a function output value. Note that support for
* property functions is not available across all properties and platforms
* at this time.
*
* @param property the feature property name
* @param stops the stops
* @param <T> the function input/output type
* @return the {@link SourceFunction}
* @see SourceFunction
* @see IdentityStops
* @see Stops#identity()
* @see Stop#stop
*/
public static <T> SourceFunction<T, T> property(@NonNull String property, @NonNull IdentityStops<T> stops) {
return new SourceFunction<>(property, stops);
}
/**
* Create an interval {@link SourceFunction}
* <p>
* Source functions allow the appearance of a map feature to change with
* its properties. Source functions can be used to visually differentiate
* types of features within the same layer or create data visualizations.
* Each stop is an array with two elements, the first is a property input
* value and the second is a function output value. Note that support for
* property functions is not available across all properties and platforms
* at this time.
*
* @param property the feature property name
* @param stops the stops
* @param <I> the function input type
* @param <O> the function output type
* @return the {@link SourceFunction}
* @see SourceFunction
* @see IntervalStops
* @see Stops#interval(Stop[])
* @see Stop#stop
*/
public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull IntervalStops<I, O> stops) {
return new SourceFunction<>(property, stops);
}
/**
* Create an categorical {@link SourceFunction}
* <p>
* Source functions allow the appearance of a map feature to change with
* its properties. Source functions can be used to visually differentiate
* types of features within the same layer or create data visualizations.
* Each stop is an array with two elements, the first is a property input
* value and the second is a function output value. Note that support for
* property functions is not available across all properties and platforms
* at this time.
*
* @param property the feature property name
* @param stops the stops
* @param <I> the function input type
* @param <O> the function output type
* @return the {@link SourceFunction}
* @see SourceFunction
* @see CategoricalStops
* @see Stops#categorical(Stop[])
* @see Stop#stop
*/
public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull CategoricalStops<I, O> stops) {
return new SourceFunction<>(property, stops);
}
/**
* Create a composite, categorical function.
* <p>
* Composite functions allow the appearance of a map feature to change with both its
* properties and zoom. Each stop is an array with two elements, the first is an object
* with a property input value and a zoom, and the second is a function output value. Note
* that support for property functions is not yet complete.
*
* @param property the feature property name for the source part of the function
* @param stops the stops
* @param <Z> the zoom function input type (Float usually)
* @param <I> the function input type for the source part of the function
* @param <O> the function output type
* @return the {@link CompositeFunction}
* @see CompositeFunction
* @see CategoricalStops
* @see Stops#categorical(Stop[])
* @see Stop#stop
*/
public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
@NonNull String property,
@NonNull CategoricalStops<Stop.CompositeValue<Z, I>, O> stops) {
return new CompositeFunction<>(property, stops);
}
/**
* Create a composite, exponential function.
* <p>
* Composite functions allow the appearance of a map feature to change with both its
* properties and zoom. Each stop is an array with two elements, the first is an object
* with a property input value and a zoom, and the second is a function output value. Note
* that support for property functions is not yet complete.
*
* @param property the feature property name for the source part of the function
* @param stops the stops
* @param <Z> the zoom function input type (Float usually)
* @param <I> the function input type for the source part of the function
* @param <O> the function output type
* @return the {@link CompositeFunction}
* @see CompositeFunction
* @see ExponentialStops
* @see Stops#exponential(Stop[])
* @see Stop#stop
*/
public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
@NonNull String property,
@NonNull ExponentialStops<Stop.CompositeValue<Z, I>, O> stops) {
return new CompositeFunction<>(property, stops);
}
/**
* Create a composite, interval function.
* <p>
* Composite functions allow the appearance of a map feature to change with both its
* properties and zoom. Each stop is an array with two elements, the first is an object
* with a property input value and a zoom, and the second is a function output value. Note
* that support for property functions is not yet complete.
*
* @param property the feature property name for the source part of the function
* @param stops the stops
* @param <Z> the zoom function input type (Float usually)
* @param <I> the function input type for the source part of the function
* @param <O> the function output type
* @return the {@link CompositeFunction}
* @see CompositeFunction
* @see IntervalStops
* @see Stops#interval(Stop[])
* @see Stop#stop
*/
public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
@NonNull String property,
@NonNull IntervalStops<Stop.CompositeValue<Z, I>, O> stops) {
return new CompositeFunction<>(property, stops);
}
// Class definition //
private final Stops<I, O> stops;
/**
* JNI Cosntructor for implementation classes
*
* @param stops the stops
*/
Function(@NonNull Stops<I, O> stops) {
this.stops = stops;
}
/**
* @return the stops in this function
*/
public Stops getStops() {
return stops;
}
/**
* Convenience method
*
* @param <S> the Stops implementation type
* @return the Stops implementation or null when the wrong type is specified
*/
@Nullable
public <S extends Stops> S getStopsAs() {
try {
// noinspection unchecked
return (S) stops;
} catch (ClassCastException exception) {
Timber.e(exception, "Stops: %s is a different type: ", stops.getClass());
return null;
}
}
/**
* INTERNAL USAGE ONLY
*
* @return a value object representation for core conversion
*/
public Map<String, Object> toValueObject() {
return stops.toValueObject();
}
@Override
public String toString() {
return String.format("%s: %s", getClass().getSimpleName(), stops);
}
}

View File

@@ -1,85 +0,0 @@
package com.mapbox.mapboxsdk.style.functions;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.style.functions.stops.Stops;
import com.mapbox.mapboxsdk.style.layers.PropertyValue;
import java.util.Map;
/**
* Source functions take Feature property names as input.
* <p>
* Source functions allow the appearance of a map feature to change with
* its properties. Source functions can be used to visually differentiate
* types of features within the same layer or create data visualizations.
* Each stop is an array with two elements, the first is a property input
* value and the second is a function output value. Note that support for
* property functions is not available across all properties and platforms
* at this time.
*
* @param <I> the input type
* @param <O> the output type
* @see Function#property
*/
public class SourceFunction<I, O> extends Function<I, O> {
private final String property;
private PropertyValue<O> defaultValue;
SourceFunction(@NonNull String property, @NonNull Stops<I, O> stops) {
this(null, property, stops);
}
/**
* JNI Constructor
*/
private SourceFunction(@Nullable O defaultValue, @NonNull String property, @NonNull Stops<I, O> stops) {
super(stops);
this.property = property;
this.defaultValue = defaultValue != null ? new PropertyValue<>(property, defaultValue) : null;
}
/**
* INTERNAL USAGE ONLY
*
* @return The feature property name
*/
public String getProperty() {
return property;
}
/**
* Set the default value
*
* @param defaultValue the default value to use when no other applies
* @return this (for chaining)
*/
public SourceFunction<I, O> withDefaultValue(PropertyValue<O> defaultValue) {
this.defaultValue = defaultValue;
return this;
}
/**
* @return the defaultValue
*/
@Nullable
public PropertyValue<O> getDefaultValue() {
return defaultValue;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> toValueObject() {
Map<String, Object> valueObject = super.toValueObject();
valueObject.put(PROPERTY_KEY, property);
if (defaultValue != null) {
valueObject.put(DEFAULT_VALUE_KEY, defaultValue.value);
}
return valueObject;
}
}

View File

@@ -1,6 +0,0 @@
/**
* Contains the Mapbox Maps Android Style Function API classes.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
*/
package com.mapbox.mapboxsdk.style.functions;

View File

@@ -1,64 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import android.support.annotation.NonNull;
import android.support.annotation.Size;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
/**
* {@link Stops} implementation for categorical functions
*
* @param <I> the {@link Stop} input type
* @param <O> the {@link Stop} output type
*/
public class CategoricalStops<I, O> extends IterableStops<I, O, Stop<I, O>> {
private final Stop<I, O>[] stops;
/**
* Create a categorical {@link Stops} implementation. Use through {@link Stops#categorical(Stop[])}
*
* @param stops the stops
*/
@SafeVarargs
public CategoricalStops(@NonNull @Size(min = 1) Stop<I, O>... stops) {
this.stops = stops;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> toValueObject() {
Map<String, Object> map = super.toValueObject();
map.put("stops", toValueObjects(stops));
return map;
}
/**
* {@inheritDoc}
*/
@Override
public String getTypeName() {
return "categorical";
}
/**
* {@inheritDoc}
*/
@Override
public Iterator<Stop<I, O>> iterator() {
return Arrays.asList(stops).iterator();
}
/**
* {@inheritDoc}
*/
@Override
public int size() {
return stops.length;
}
}

View File

@@ -1,97 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import android.support.annotation.NonNull;
import android.support.annotation.Size;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
/**
* The {@link Stops} implementation for exponential functions
*
* @param <I> the input type
* @param <O> the output type
*/
public class ExponentialStops<I, O> extends IterableStops<I, O, Stop<I, O>> {
private float base;
private final Stop<I, O>[] stops;
/**
* Create exponential stops with an explicit base. Use through {@link Stops#exponential(Stop[])}
*
* @param base The exponential base of the interpolation curve. It controls the rate at which the function output
* increases. Higher values make the output increase more towards the high end of the range.
* With values close to 1 the output increases linearly.
* @param stops the stops
*/
@SafeVarargs
public ExponentialStops(Float base, @NonNull @Size(min = 1) Stop<I, O>... stops) {
this.base = base != null ? base : 1.0f;
this.stops = stops;
}
/**
* Create exponential stops without an explicit base. Use through {@link Stops#exponential(Stop[])}
*
* @param stops the stops
*/
@SafeVarargs
public ExponentialStops(@NonNull @Size(min = 1) Stop<I, O>... stops) {
this(null, stops);
}
/**
* Set the exponential base
*
* @param base the base to use in the exponential function
* @return this (for chaining)
*/
public ExponentialStops<I, O> withBase(float base) {
this.base = base;
return this;
}
/**
* @return The exponential base
*/
public float getBase() {
return base;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> toValueObject() {
Map<String, Object> map = super.toValueObject();
map.put("base", base);
map.put("stops", toValueObjects(stops));
return map;
}
/**
* {@inheritDoc}
*/
@Override
public String getTypeName() {
return "exponential";
}
/**
* {@inheritDoc}
*/
@Override
public Iterator<Stop<I, O>> iterator() {
return Arrays.asList(stops).iterator();
}
/**
* {@inheritDoc}
*/
@Override
public int size() {
return stops.length;
}
}

View File

@@ -1,18 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
/**
* The {@link Stops} implementation for identity functions
*
* @param <T> the input/output type
*/
public class IdentityStops<T> extends Stops<T, T> {
/**
* {@inheritDoc}
*/
@Override
protected String getTypeName() {
return "identity";
}
}

View File

@@ -1,58 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import android.support.annotation.NonNull;
import android.support.annotation.Size;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
/**
* The {@link Stops} implementation for interval functions
*
* @param <I> the input type
* @param <O> the output type
*/
public class IntervalStops<I, O> extends IterableStops<I, O, Stop<I, O>> {
private final Stop<I, O>[] stops;
@SafeVarargs
public IntervalStops(@NonNull @Size(min = 1) Stop<I, O>... stops) {
this.stops = stops;
}
/**
* {@inheritDoc}
*/
@Override
public String getTypeName() {
return "interval";
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> toValueObject() {
Map<String, Object> map = super.toValueObject();
map.put("stops", toValueObjects(stops));
return map;
}
/**
* @return an {@link Iterator} for the contained stops
*/
@Override
public Iterator<Stop<I, O>> iterator() {
return Arrays.asList(stops).iterator();
}
/**
* @return The number of contained stops
*/
@Override
public int size() {
return stops.length;
}
}

View File

@@ -1,52 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import java.util.Iterator;
/**
* Base class for {@link Stops} implementations with a collection of stops
*
* @param <I> the {@link Stops} input type
* @param <O> the {@link Stops} output type
* @param <S> the {@link Iterable} element type (usually {@link Stop})
*/
public abstract class IterableStops<I, O, S> extends Stops<I, O> implements Iterable<S> {
/**
* @return The size of the contained stops collection
*/
public abstract int size();
/**
* Convenience function to toValueObjects an array of stops to an array of value objects
*
* @param stops the stops to toValueObjects
* @return the stops as value objects
*/
Object[] toValueObjects(Stop<I, O>[] stops) {
if (stops != null) {
Object[] stopsValue = new Object[stops.length];
for (int i = 0; i < stopsValue.length; i++) {
Stop stop = stops[i];
stopsValue[i] = stop.toValueObject();
}
return stopsValue;
}
return null;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
Iterator<S> iterator = iterator();
while (iterator.hasNext()) {
S stop = iterator.next();
buffer.append(stop);
if (iterator.hasNext()) {
buffer.append(",");
}
}
return String.format("%s: [%s]", super.toString(), buffer.toString());
}
}

View File

@@ -1,109 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import com.mapbox.mapboxsdk.style.functions.Function;
import com.mapbox.mapboxsdk.style.layers.PropertyValue;
import java.util.HashMap;
import java.util.Map;
/**
* A stop represents a certain point in the range of this function
*
* @param <I> input the stop (function) input type
* @param <O> output the stop (function) output type
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
*/
public class Stop<I, O> {
/**
* Creates a {@link Stop} to use in a {@link Function}
*
* @param in the input for the stop
* @param output the output for the stop
* @param <I> the input property type
* @param <O> the output property type
* @return the {@link Stop}
*/
public static <I, O> Stop<I, O> stop(I in, PropertyValue<O> output) {
return new Stop<>(in, output.value);
}
/**
* Create a composite {@link Stop} for use in a {@link com.mapbox.mapboxsdk.style.functions.CompositeFunction}
*
* @param zoom the zoom input
* @param value the feature property input
* @param output the output for the stop
* @param <Z> the zoom type
* @param <I> the feature property input type
* @param <O> the output property type
* @return the {@link Stop}
* @see Function#composite(String, ExponentialStops)
*/
public static <Z extends Number, I, O> Stop<Stop.CompositeValue<Z, I>, O> stop(Z zoom,
I value,
PropertyValue<O> output) {
return new Stop<>(new Stop.CompositeValue<>(zoom, value), output.value);
}
/**
* Represents a composite input value for composite functions (eg zoom and feature property value)
*
* @param <Z> the zoom input type (typically Float)
* @param <V> the feature property input type
*/
public static class CompositeValue<Z extends Number, V> {
public final Z zoom;
public final V value;
CompositeValue(Z zoom, V value) {
this.zoom = zoom;
this.value = value;
}
/**
* INTERNAL USAGE ONLY
*
* @return the value object representation for core conversion
*/
Map<String, Object> toValueObject() {
HashMap<String, Object> map = new HashMap<>();
map.put("zoom", zoom);
map.put("value", value);
return map;
}
@Override
public String toString() {
return String.format("[zoom: %s, value: %s]", zoom, value);
}
}
/**
* The input type
*/
public final I in;
/**
* The output type
*/
public final O out;
Stop(I in, O out) {
this.in = in;
this.out = out;
}
/**
* INTERNAL USAGE ONLY
*
* @return an array representation of the Stop
*/
Object[] toValueObject() {
return new Object[] {in instanceof CompositeValue ? ((CompositeValue) in).toValueObject() : in, out};
}
@Override
public String toString() {
return String.format("[%s, %s]", in, out);
}
}

View File

@@ -1,99 +0,0 @@
package com.mapbox.mapboxsdk.style.functions.stops;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Size;
import java.util.HashMap;
import java.util.Map;
/**
* The base class for different stops implementations
*
* @param <I> the input type
* @param <O> the output type
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
*/
public abstract class Stops<I, O> {
/**
* Convenience method for use in function declarations
*
* @param stops the collections of discrete stops
* @param <I> the Stops input type
* @param <O> the Stops output type
* @return the {@link Stops} implementation
* @see Stop#stop
* @see CategoricalStops
*/
@SafeVarargs
public static <I, O> CategoricalStops<I, O> categorical(@NonNull @Size(min = 1) Stop<I, O>... stops) {
return new CategoricalStops<>(stops);
}
/**
* Convenience method for use in function declarations
*
* @param stops the collections of discrete stops
* @param <I> the Stops input type
* @param <O> the Stops output type
* @return the {@link Stops} implementation
* @see Stop#stop
* @see ExponentialStops
*/
@SafeVarargs
public static <I, O> ExponentialStops<I, O> exponential(@NonNull @Size(min = 1) Stop<I, O>... stops) {
return new ExponentialStops<>(stops);
}
/**
* Convenience method for use in function declarations
*
* @param <T> the Stops input/output type
* @return the {@link IdentityStops} implementation
* @see Stop#stop
* @see IdentityStops
*/
public static <T> IdentityStops<T> identity() {
return new IdentityStops<>();
}
/**
* Convenience method for use in function declarations
*
* @param stops the collections of discrete stops
* @param <I> the Stops input type
* @param <O> the Stops output type
* @return the {@link Stops} implementation
* @see Stop#stop
* @see IntervalStops
*/
@SafeVarargs
public static <I, O> IntervalStops<I, O> interval(@NonNull @Size(min = 1) Stop<I, O>... stops) {
return new IntervalStops<>(stops);
}
/**
* INTERNAL USAGE ONLY
*
* @return the value object representation for conversion to core
*/
@CallSuper
public Map<String, Object> toValueObject() {
HashMap<String, Object> map = new HashMap<>();
map.put("type", getTypeName());
return map;
}
/**
* INTERNAL USAGE ONLY
*
* @return the unique type name as a string according to the style specification
*/
protected abstract String getTypeName();
@Override
public String toString() {
return getTypeName();
}
}

View File

@@ -1,6 +0,0 @@
/**
* Contains the Mapbox Maps Android Style Function Stop implementation API classes.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
*/
package com.mapbox.mapboxsdk.style.functions.stops;

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class CircleLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public CircleLayer withFilter(Filter.Statement filter) {
public CircleLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*

View File

@@ -9,20 +9,8 @@ package com.mapbox.mapboxsdk.style.layers;
public class CustomLayer extends Layer {
public CustomLayer(String id,
long context,
long initializeFunction,
long renderFunction,
long deinitializeFunction) {
this(id, context, initializeFunction, renderFunction, 0L, deinitializeFunction);
}
public CustomLayer(String id,
long context,
long initializeFunction,
long renderFunction,
long contextLostFunction,
long deinitializeFunction) {
initialize(id, initializeFunction, renderFunction, contextLostFunction, deinitializeFunction, context);
long host) {
initialize(id, host);
}
public CustomLayer(long nativePtr) {
@@ -33,9 +21,7 @@ public class CustomLayer extends Layer {
nativeUpdate();
}
protected native void initialize(String id, long initializeFunction, long renderFunction,
long contextLostFunction, long deinitializeFunction,
long context);
protected native void initialize(String id, long host);
protected native void nativeUpdate();

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class FillExtrusionLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public FillExtrusionLayer withFilter(Filter.Statement filter) {
public FillExtrusionLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class FillLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public FillLayer withFilter(Filter.Statement filter) {
public FillLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*

View File

@@ -1,230 +0,0 @@
package com.mapbox.mapboxsdk.style.layers;
import java.util.ArrayList;
import java.util.Collections;
/**
* Utility to build filter expressions more easily.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-filter">The online documentation</a>
*/
public class Filter {
/**
* Base Filter statement. Subclassed to provide concrete statements.
*/
public abstract static class Statement {
protected final String operator;
public Statement(String operator) {
this.operator = operator;
}
/**
* Generate a raw array representation of the filter
*
* @return the filter represented as an array
*/
public abstract Object[] toArray();
}
/**
* Represents a {@link Filter} statement. Can be unary (eg `has()`, etc) or take any number of values.
*/
private static class SimpleStatement extends Statement {
private final String key;
private final Object[] values;
/**
* @param operator the operator (eg `=`, etc)
* @param key the property key
* @param values the values to operate on, if any
*/
SimpleStatement(String operator, String key, Object... values) {
super(operator);
this.key = key;
this.values = values;
}
/**
* {@inheritDoc}
*/
@Override
public Object[] toArray() {
ArrayList<Object> array = new ArrayList<>(2 + values.length);
array.add(operator);
array.add(key);
Collections.addAll(array, values);
return array.toArray();
}
}
/**
* Represents a collection of {@link Statement}s with an operator that describes their relationship
*/
private static class CompoundStatement extends Statement {
private final Statement[] statements;
/**
* @param operator the relationship operator
* @param statements the statements to compound
*/
CompoundStatement(String operator, Statement... statements) {
super(operator);
this.statements = statements;
}
/**
* {@inheritDoc}
*/
@Override
public Object[] toArray() {
ArrayList<Object> array = new ArrayList<>(1 + statements.length);
array.add(operator);
for (Statement statement : statements) {
array.add(statement.toArray());
}
return array.toArray();
}
}
/**
* Groups a collection of statements in an 'all' relationship
*
* @param statements the collection of statements
* @return the statements compounded
*/
public static Statement all(Statement... statements) {
return new CompoundStatement("all", statements);
}
/**
* Groups a collection of statements in an 'any' relationship
*
* @param statements the collection of statements
* @return the statements compounded
*/
public static Statement any(Statement... statements) {
return new CompoundStatement("any", statements);
}
/**
* Groups a collection of statements in an 'none' relationship
*
* @param statements the collection of statements
* @return the statements compounded
*/
public static Statement none(Statement... statements) {
return new CompoundStatement("none", statements);
}
/**
* Check the property's existence
*
* @param key the property key
* @return the statement
*/
public static Statement has(String key) {
return new SimpleStatement("has", key);
}
/**
* Check the property's existence, negated
*
* @param key the property key
* @return the statement
*/
public static Statement notHas(String key) {
return new SimpleStatement("!has", key);
}
/**
* Check the property equals the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement eq(String key, Object value) {
return new SimpleStatement("==", key, value);
}
/**
* Check the property does not equals the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement neq(String key, Object value) {
return new SimpleStatement("!=", key, value);
}
/**
* Check the property exceeds the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement gt(String key, Object value) {
return new SimpleStatement(">", key, value);
}
/**
* Check the property exceeds or equals the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement gte(String key, Object value) {
return new SimpleStatement(">=", key, value);
}
/**
* Check the property does not exceeds the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement lt(String key, Object value) {
return new SimpleStatement("<", key, value);
}
/**
* Check the property equals or does not exceeds the given value
*
* @param key the property key
* @param value the value to check against
* @return the statement
*/
public static Statement lte(String key, Object value) {
return new SimpleStatement("<=", key, value);
}
/**
* Check the property is within the given set
*
* @param key the property key
* @param values the set of values to check against
* @return the statement
*/
public static Statement in(String key, Object... values) {
return new SimpleStatement("in", key, values);
}
/**
* Check the property is not within the given set
*
* @param key the property key
* @param values the set of values to check against
* @return the statement
*/
public static Statement notIn(String key, Object... values) {
return new SimpleStatement("!in", key, values);
}
}

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class HeatmapLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public HeatmapLayer withFilter(Filter.Statement filter) {
public HeatmapLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*
@@ -167,6 +185,32 @@ public class HeatmapLayer extends Layer {
nativeSetHeatmapIntensityTransition(options.getDuration(), options.getDelay());
}
/**
* Get the HeatmapColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getHeatmapColor() {
return (PropertyValue<String>) new PropertyValue("heatmap-color", nativeGetHeatmapColor());
}
/**
* Defines the color of each pixel based on its density value in a heatmap. Should be an expression that uses `["heatmap-density"]` as input.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getHeatmapColorAsInt() {
PropertyValue<String> value = getHeatmapColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("heatmap-color was set as a Function");
}
}
/**
* Get the HeatmapOpacity property
*
@@ -209,6 +253,8 @@ public class HeatmapLayer extends Layer {
private native void nativeSetHeatmapIntensityTransition(long duration, long delay);
private native Object nativeGetHeatmapColor();
private native Object nativeGetHeatmapOpacity();
private native TransitionOptions nativeGetHeatmapOpacityTransition();

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**

View File

@@ -2,8 +2,9 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.NonNull;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.functions.Function;
/**
* Base class for the different Layer types
@@ -72,6 +73,8 @@ public abstract class Layer {
protected native void nativeSetFilter(Object[] filter);
protected native JsonElement nativeGetFilter();
protected native void nativeSetSourceLayer(String sourceLayer);
protected native String nativeGetSourceLayer();
@@ -89,12 +92,8 @@ public abstract class Layer {
}
private Object convertValue(Object value) {
if (value != null) {
if (value instanceof Function) {
return ((Function) value).toValueObject();
} else if (value instanceof Expression) {
return ((Expression) value).toArray();
}
if (value != null && value instanceof Expression) {
return ((Expression) value).toArray();
}
return value;
}

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class LineLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public LineLayer withFilter(Filter.Statement filter) {
public LineLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*

View File

@@ -4,8 +4,9 @@ import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.exceptions.ConversionException;
import com.mapbox.mapboxsdk.style.functions.Function;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.utils.ColorUtils;
import timber.log.Timber;
@@ -40,12 +41,27 @@ public class PropertyValue<T> {
}
/**
* Returns if this is a function.
* Returns if this is a expression.
*
* @return true if is a function, false if not
* @return true if this is a expression, false if not
*/
public boolean isFunction() {
return !isNull() && value instanceof Function;
public boolean isExpression() {
return !isNull() && value instanceof JsonArray;
}
/**
* Get the expression of the property.
*
* @return the property expression
*/
@Nullable
public Expression getExpression() {
if (isExpression()) {
return Expression.Converter.convert((JsonArray) value);
} else {
Timber.w("not a expression, try value");
return null;
}
}
/**
@@ -54,18 +70,7 @@ public class PropertyValue<T> {
* @return true if is a value, false if not
*/
public boolean isValue() {
return !isNull() && !isFunction();
}
@Nullable
public Function<?, T> getFunction() {
if (isFunction()) {
// noinspection unchecked
return (Function<?, T>) value;
} else {
Timber.w("not a function, try value");
return null;
}
return !isNull() && !isExpression();
}
/**
@@ -77,7 +82,7 @@ public class PropertyValue<T> {
public T getValue() {
if (isValue()) {
// noinspection unchecked
return (T) value;
return value;
} else {
Timber.w("not a value, try function");
return null;
@@ -114,4 +119,4 @@ public class PropertyValue<T> {
public String toString() {
return String.format("%s: %s", name, value);
}
}
}

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**

View File

@@ -4,10 +4,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -69,25 +72,40 @@ public class SymbolLayer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public SymbolLayer withFilter(Filter.Statement filter) {
public SymbolLayer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
/**
* Set a property or properties.
*

View File

@@ -9,10 +9,13 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
/**
@@ -89,25 +92,40 @@ public class <%- camelize(type) %>Layer extends Layer {
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
*/
public void setFilter(Filter.Statement filter) {
public void setFilter(Expression filter) {
nativeSetFilter(filter.toArray());
}
/**
* Set a single filter.
* Set a single expression filter.
*
* @param filter the filter to set
* @param filter the expression filter to set
* @return This
*/
public <%- camelize(type) %>Layer withFilter(Filter.Statement filter) {
public <%- camelize(type) %>Layer withFilter(Expression filter) {
setFilter(filter);
return this;
}
/**
* Get a single expression filter.
*
* @return the expression filter to get
*/
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
return expression;
}
<% } -%>
/**
* Set a property or properties.

View File

@@ -8,9 +8,7 @@ package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.ColorInt;
import com.mapbox.mapboxsdk.style.functions.CameraFunction;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.functions.Function;
import java.util.Locale;
@@ -31,18 +29,6 @@ public class PropertyFactory {
return new LayoutPropertyValue<>("visibility", value);
}
/**
* Set the property visibility.
*
* @param <T> the function input type
* @param function the visibility function
* @return property wrapper around a String function
*/
@Deprecated
public static <T> PropertyValue<Function<T, String>> visibility(Function<T, String> function) {
return new LayoutPropertyValue<>("visibility", function);
}
<% for (const property of paintProperties) { -%>
<% if (property.type == 'color') { -%>
/**
@@ -76,35 +62,6 @@ public class PropertyFactory {
return new PaintPropertyValue<>("<%- property.name %>", expression);
}
<% if (supportsPropertyFunction(property)) { -%>
/**
* <%- propertyFactoryMethodDoc(property) %>
*
* @param <T> the function input type
* @param function a wrapper function for <%- propertyType(property) %>
* @return property wrapper around a <%- propertyType(property) %> function
*/
@Deprecated
public static <T> PropertyValue<Function<T, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<T, <%- propertyType(property) %>> function) {
return new PaintPropertyValue<>("<%- property.name %>", function);
}
<% } else if (supportsZoomFunction(property)) { -%>
/**
* <%- propertyFactoryMethodDoc(property) %>
*
* @param <Z> the zoom parameter type
* @param function a wrapper {@link CameraFunction} for <%- propertyType(property) %>
* @return property wrapper around a <%- propertyType(property) %> function
*/
@Deprecated
public static <Z extends Number> PropertyValue<CameraFunction<Z, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(CameraFunction<Z, <%- propertyType(property) %>> function) {
return new PaintPropertyValue<>("<%- property.name %>", function);
}
<% } -%>
<% } -%>
<% for (const property of layoutProperties) { -%>
/**
@@ -127,33 +84,6 @@ public class PropertyFactory {
return new LayoutPropertyValue<>("<%- property.name %>", value);
}
<% if (supportsPropertyFunction(property)) { -%>
/**
* <%- propertyFactoryMethodDoc(property) %>
*
* @param <T> the function input type
* @param function a wrapper function for <%- propertyType(property) %>
* @return property wrapper around a <%- propertyType(property) %> function
*/
public static <T> PropertyValue<Function<T, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<T, <%- propertyType(property) %>> function) {
return new LayoutPropertyValue<>("<%- property.name %>", function);
}
<% } else if (supportsZoomFunction(property)) { -%>
/**
* <%- propertyFactoryMethodDoc(property) %>
*
* @param <Z> the zoom parameter type
* @param function a wrapper {@link CameraFunction} for <%- propertyType(property) %>
* @return property wrapper around a <%- propertyType(property) %> function
*/
public static <Z extends Number> PropertyValue<CameraFunction<Z, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(CameraFunction<Z, <%- propertyType(property) %>> function) {
return new LayoutPropertyValue<>("<%- property.name %>", function);
}
<% } -%>
<% } -%>
public static String colorToRgbaString(@ColorInt int value) {
return String.format(Locale.US,"rgba(%d, %d, %d, %d)",

View File

@@ -48,7 +48,7 @@ public class Light {
}
/**
* Set the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0° (0° when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0° when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0°, directly above, to 180°, directly below).
* Set the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0&#xB0; (0&#xB0; when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0&#xB0; when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0&#xB0;, directly above, to 180&#xB0;, directly below).
*
* @param position of the light
*/
@@ -57,7 +57,7 @@ public class Light {
}
/**
* Get the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0° (0° when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0° when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0°, directly above, to 180°, directly below).
* Get the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0&#xB0; (0&#xB0; when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0&#xB0; when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0&#xB0;, directly above, to 180&#xB0;, directly below).
*
* @return position as Position
*/

View File

@@ -5,11 +5,11 @@ package com.mapbox.mapboxsdk.style.light;
* <p>
* The position is constructed out of a radial coordinate, an azimuthal angle and a polar angle.
* where the radial coordinate indicates the distance from the center of the base of an object to its light, the
* azimuthal angle indicates the position of the light relative to 0° (0° when
* azimuthal angle indicates the position of the light relative to 0&#xB0; (0&#xB0; when
* {@link com.mapbox.mapboxsdk.style.layers.Property.ANCHOR} is set to viewport corresponds to the top of the
* viewport, or 0° when {@link com.mapbox.mapboxsdk.style.layers.Property.ANCHOR} is set to map corresponds to due
* viewport, or 0&#xB0; when {@link com.mapbox.mapboxsdk.style.layers.Property.ANCHOR} is set to map corresponds to due
* north, and degrees proceed clockwise), and polar indicates the height of the light
* (from 0°, directly above, to 180°, directly below).
* (from 0&#xB0;, directly above, to 180&#xB0;, directly below).
*/
public class Position {
@@ -21,7 +21,7 @@ public class Position {
* Creates a Position from a radial coordinate, an azimuthal angle and a polar angle.
*
* @param radialCoordinate the distance from the center of the base of an object to its light
* @param azimuthalAngle the position of the light relative to 0°
* @param azimuthalAngle the position of the light relative to 0&#xB0;
* @param polarAngle the height of the light
*/
public Position(float radialCoordinate, float azimuthalAngle, float polarAngle) {

View File

@@ -8,7 +8,7 @@ import android.support.annotation.WorkerThread;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.style.layers.Filter;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -94,11 +94,11 @@ public class CustomGeometrySource extends Source {
/**
* Queries the source for features.
*
* @param filter an optional filter statement to filter the returned Features
* @param filter an optional filter expression to filter the returned Features
* @return the features
*/
@NonNull
public List<Feature> querySourceFeatures(@Nullable Filter.Statement filter) {
public List<Feature> querySourceFeatures(@Nullable Expression filter) {
Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}

View File

@@ -7,7 +7,7 @@ import android.support.annotation.UiThread;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Geometry;
import com.mapbox.mapboxsdk.style.layers.Filter;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import java.net.URL;
import java.util.ArrayList;
@@ -187,7 +187,7 @@ public class GeoJsonSource extends Source {
*
* @param geometry the GeoJSON {@link Geometry} to set
*/
public void setGeoJson(Geometry<?> geometry) {
public void setGeoJson(Geometry geometry) {
nativeSetGeometry(geometry);
}
@@ -238,11 +238,11 @@ public class GeoJsonSource extends Source {
/**
* Queries the source for features.
*
* @param filter an optional filter statement to filter the returned Features
* @param filter an optional filter expression to filter the returned Features
* @return the features
*/
@NonNull
public List<Feature> querySourceFeatures(@Nullable Filter.Statement filter) {
public List<Feature> querySourceFeatures(@Nullable Expression filter) {
Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}
@@ -259,7 +259,7 @@ public class GeoJsonSource extends Source {
private native void nativeSetFeature(Feature feature);
private native void nativeSetGeometry(Geometry<?> geometry);
private native void nativeSetGeometry(Geometry geometry);
private native Feature[] querySourceFeatures(Object[] filter);

View File

@@ -9,6 +9,7 @@ import java.util.Map;
/**
* Tile set, allows using TileJson specification as source.
* Note that `encoding` is only relevant to `raster-dem` sources, and is not supported in the TileJson spec.
*
* @see <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">The tileset specification</a>
*/
@@ -28,6 +29,7 @@ public class TileSet {
private Float maxZoom;
private Float[] bounds;
private Float[] center;
private String encoding;
/**
* @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented
@@ -246,6 +248,20 @@ public class TileSet {
this.bounds = bounds;
}
public String getEncoding() {
return encoding;
}
/**
* Default: "mapbox". The encoding formula for a raster-dem tileset.
* Supported values are "mapbox" and "terrarium".
*
* @param encoding the String encoding formula to set
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public Float[] getCenter() {
return center;
}
@@ -313,6 +329,10 @@ public class TileSet {
if (center != null) {
result.put("center", center);
}
if (encoding != null) {
result.put("encoding", encoding);
}
return result;
}

Some files were not shown because too many files have changed in this diff Show More