Adds checkstyle to CI (#7442)

* adds checkstyle to CI

* fixed gradlew path

* resolved testapp checkstyle violations

* added back mapboxMap variable for test

* checkstyle annotations

* checkstyle SDK round 1

* maps package checkstyle

* rest of SDK checkstyle

* checkstyle gesture library

* checkstyle test

* finished rest of test checkstyle

* resolved all checkstyle errors

* fixed class name

* removed old test file

* fixed camera postion test

* fixed native crash
This commit is contained in:
Cameron Mace
2016-12-16 16:19:15 -05:00
committed by GitHub
parent f95b4838ea
commit 20b958301e
266 changed files with 40182 additions and 39049 deletions

View File

@@ -6,19 +6,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
*
* <p>
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,129 +33,128 @@ import android.view.MotionEvent;
* POSSIBILITY OF SUCH DAMAGE.
*/
public abstract class BaseGestureDetector {
protected final Context mContext;
protected boolean mGestureInProgress;
protected final Context context;
protected boolean gestureInProgress;
protected MotionEvent mPrevEvent;
protected MotionEvent mCurrEvent;
protected MotionEvent prevEvent;
protected MotionEvent currEvent;
protected float mCurrPressure;
protected float mPrevPressure;
protected long mTimeDelta;
protected float currPressure;
protected float prevPressure;
protected long timeDelta;
/**
* This value is the threshold ratio between the previous combined pressure
* and the current combined pressure. When pressure decreases rapidly
* between events the position values can often be imprecise, as it usually
* indicates that the user is in the process of lifting a pointer off of the
* device. This value was tuned experimentally.
*/
protected static final float PRESSURE_THRESHOLD = 0.67f;
/**
* This value is the threshold ratio between the previous combined pressure
* and the current combined pressure. When pressure decreases rapidly
* between events the position values can often be imprecise, as it usually
* indicates that the user is in the process of lifting a pointer off of the
* device. This value was tuned experimentally.
*/
protected static final float PRESSURE_THRESHOLD = 0.67f;
public BaseGestureDetector(Context context) {
mContext = context;
public BaseGestureDetector(Context context) {
this.context = context;
}
/**
* All gesture detectors need to be called through this method to be able to
* detect gestures. This method delegates work to handler methods
* (handleStartProgressEvent, handleInProgressEvent) implemented in
* extending classes.
*
* @param event MotionEvent
* @return {@code true} as handled
*/
public boolean onTouchEvent(MotionEvent event) {
final int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
if (!gestureInProgress) {
handleStartProgressEvent(actionCode, event);
} else {
handleInProgressEvent(actionCode, event);
}
return true;
}
/**
* All gesture detectors need to be called through this method to be able to
* detect gestures. This method delegates work to handler methods
* (handleStartProgressEvent, handleInProgressEvent) implemented in
* extending classes.
*
* @param event MotionEvent
* @return {@code true} as handled
*/
public boolean onTouchEvent(MotionEvent event) {
final int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
if (!mGestureInProgress) {
handleStartProgressEvent(actionCode, event);
} else {
handleInProgressEvent(actionCode, event);
}
return true;
/**
* Called when the current event occurred when NO gesture is in progress
* yet. The handling in this implementation may set the gesture in progress
* (via gestureInProgress) or out of progress
*
* @param actionCode Action Code from MotionEvent
* @param event MotionEvent
*/
protected abstract void handleStartProgressEvent(int actionCode,
MotionEvent event);
/**
* Called when the current event occurred when a gesture IS in progress. The
* handling in this implementation may set the gesture out of progress (via
* gestureInProgress).
*
* @param actionCode Action Code from MotionEvent
* @param event MotionEvent
*/
protected abstract void handleInProgressEvent(int actionCode,
MotionEvent event);
protected void updateStateByEvent(MotionEvent curr) {
final MotionEvent prev = prevEvent;
// Reset currEvent
if (currEvent != null) {
currEvent.recycle();
currEvent = null;
}
currEvent = MotionEvent.obtain(curr);
/**
* Called when the current event occurred when NO gesture is in progress
* yet. The handling in this implementation may set the gesture in progress
* (via mGestureInProgress) or out of progress
*
* @param actionCode Action Code from MotionEvent
* @param event MotionEvent
*/
protected abstract void handleStartProgressEvent(int actionCode,
MotionEvent event);
// Delta time
timeDelta = curr.getEventTime() - prev.getEventTime();
/**
* Called when the current event occurred when a gesture IS in progress. The
* handling in this implementation may set the gesture out of progress (via
* mGestureInProgress).
*
*
* @param actionCode Action Code from MotionEvent
* @param event MotionEvent
*/
protected abstract void handleInProgressEvent(int actionCode,
MotionEvent event);
// Pressure
currPressure = curr.getPressure(curr.getActionIndex());
prevPressure = prev.getPressure(prev.getActionIndex());
}
protected void updateStateByEvent(MotionEvent curr) {
final MotionEvent prev = mPrevEvent;
// Reset mCurrEvent
if (mCurrEvent != null) {
mCurrEvent.recycle();
mCurrEvent = null;
}
mCurrEvent = MotionEvent.obtain(curr);
// Delta time
mTimeDelta = curr.getEventTime() - prev.getEventTime();
// Pressure
mCurrPressure = curr.getPressure(curr.getActionIndex());
mPrevPressure = prev.getPressure(prev.getActionIndex());
protected void resetState() {
if (prevEvent != null) {
prevEvent.recycle();
prevEvent = null;
}
protected void resetState() {
if (mPrevEvent != null) {
mPrevEvent.recycle();
mPrevEvent = null;
}
if (mCurrEvent != null) {
mCurrEvent.recycle();
mCurrEvent = null;
}
mGestureInProgress = false;
if (currEvent != null) {
currEvent.recycle();
currEvent = null;
}
gestureInProgress = false;
}
/**
* Returns {@code true} if a gesture is currently in progress.
*
* @return {@code true} if a gesture is currently in progress, {@code false}
* otherwise.
*/
public boolean isInProgress() {
return mGestureInProgress;
}
/**
* Returns {@code true} if a gesture is currently in progress.
*
* @return {@code true} if a gesture is currently in progress, {@code false}
* otherwise.
*/
public boolean isInProgress() {
return gestureInProgress;
}
/**
* Return the time difference in milliseconds between the previous accepted
* GestureDetector event and the current GestureDetector event.
*
* @return Time difference since the last move event in milliseconds.
*/
public long getTimeDelta() {
return mTimeDelta;
}
/**
* Return the time difference in milliseconds between the previous accepted
* GestureDetector event and the current GestureDetector event.
*
* @return Time difference since the last move event in milliseconds.
*/
public long getTimeDelta() {
return timeDelta;
}
/**
* Return the event time of the current GestureDetector event being
* processed.
*
* @return Current GestureDetector event time in milliseconds.
*/
public long getEventTime() {
return mCurrEvent.getEventTime();
}
/**
* Return the event time of the current GestureDetector event being
* processed.
*
* @return Current GestureDetector event time in milliseconds.
*/
public long getEventTime() {
return currEvent.getEventTime();
}
}

View File

@@ -7,19 +7,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
*
* <p>
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,151 +35,151 @@ import android.view.MotionEvent;
*/
public class MoveGestureDetector extends BaseGestureDetector {
/**
* Listener which must be implemented which is used by MoveGestureDetector
* to perform callbacks to any implementing class which is registered to a
* MoveGestureDetector via the constructor.
*
* @see MoveGestureDetector.SimpleOnMoveGestureListener
*/
public interface OnMoveGestureListener {
public boolean onMove(MoveGestureDetector detector);
/**
* Listener which must be implemented which is used by MoveGestureDetector
* to perform callbacks to any implementing class which is registered to a
* MoveGestureDetector via the constructor.
*
* @see MoveGestureDetector.SimpleOnMoveGestureListener
*/
public interface OnMoveGestureListener {
public boolean onMove(MoveGestureDetector detector);
public boolean onMoveBegin(MoveGestureDetector detector);
public boolean onMoveBegin(MoveGestureDetector detector);
public void onMoveEnd(MoveGestureDetector detector);
public void onMoveEnd(MoveGestureDetector detector);
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnMoveGestureListener.
*/
public static class SimpleOnMoveGestureListener implements
OnMoveGestureListener {
public boolean onMove(MoveGestureDetector detector) {
return false;
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnMoveGestureListener.
*/
public static class SimpleOnMoveGestureListener implements
OnMoveGestureListener {
public boolean onMove(MoveGestureDetector detector) {
return false;
public boolean onMoveBegin(MoveGestureDetector detector) {
return true;
}
public void onMoveEnd(MoveGestureDetector detector) {
// Do nothing, overridden implementation may be used
}
}
private static final PointF FOCUS_DELTA_ZERO = new PointF();
private final OnMoveGestureListener listener;
private PointF focusExternal = new PointF();
private PointF focusDeltaExternal = new PointF();
public MoveGestureDetector(Context context, OnMoveGestureListener listener) {
super(context);
this.listener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_DOWN:
resetState(); // In case we missed an UP/CANCEL event
prevEvent = MotionEvent.obtain(event);
timeDelta = 0;
updateStateByEvent(event);
break;
case MotionEvent.ACTION_MOVE:
gestureInProgress = listener.onMoveBegin(this);
break;
}
}
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
listener.onMoveEnd(this);
resetState();
break;
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted.
if (currPressure / prevPressure > PRESSURE_THRESHOLD) {
final boolean updatePrevious = listener.onMove(this);
if (updatePrevious) {
prevEvent.recycle();
prevEvent = MotionEvent.obtain(event);
}
}
break;
}
}
public boolean onMoveBegin(MoveGestureDetector detector) {
return true;
}
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
public void onMoveEnd(MoveGestureDetector detector) {
// Do nothing, overridden implementation may be used
}
final MotionEvent prev = prevEvent;
// Focus intenal
PointF currFocusInternal = determineFocalPoint(curr);
PointF prevFocusInternal = determineFocalPoint(prev);
// Focus external
// - Prevent skipping of focus delta when a finger is added or removed
boolean skipNextMoveEvent = prev.getPointerCount() != curr
.getPointerCount();
focusDeltaExternal = skipNextMoveEvent ? FOCUS_DELTA_ZERO
: new PointF(currFocusInternal.x - prevFocusInternal.x,
currFocusInternal.y - prevFocusInternal.y);
// - Don't directly use mFocusInternal (or skipping will occur). Add
// unskipped delta values to focusExternal instead.
focusExternal.x += focusDeltaExternal.x;
focusExternal.y += focusDeltaExternal.y;
}
/**
* Determine (multi)finger focal point (a.k.a. center point between all
* fingers)
*
* @param motionEvent a {@link MotionEvent} object.
* @return PointF focal point
*/
private PointF determineFocalPoint(MotionEvent motionEvent) {
// Number of fingers on screen
final int pCount = motionEvent.getPointerCount();
float x = 0.0f;
float y = 0.0f;
for (int i = 0; i < pCount; i++) {
x += motionEvent.getX(i);
y += motionEvent.getY(i);
}
private static final PointF FOCUS_DELTA_ZERO = new PointF();
return new PointF(x / pCount, y / pCount);
}
private final OnMoveGestureListener mListener;
public float getFocusX() {
return focusExternal.x;
}
private PointF mFocusExternal = new PointF();
private PointF mFocusDeltaExternal = new PointF();
public float getFocusY() {
return focusExternal.y;
}
public MoveGestureDetector(Context context, OnMoveGestureListener listener) {
super(context);
mListener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_DOWN:
resetState(); // In case we missed an UP/CANCEL event
mPrevEvent = MotionEvent.obtain(event);
mTimeDelta = 0;
updateStateByEvent(event);
break;
case MotionEvent.ACTION_MOVE:
mGestureInProgress = mListener.onMoveBegin(this);
break;
}
}
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mListener.onMoveEnd(this);
resetState();
break;
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted.
if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
final boolean updatePrevious = mListener.onMove(this);
if (updatePrevious) {
mPrevEvent.recycle();
mPrevEvent = MotionEvent.obtain(event);
}
}
break;
}
}
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
final MotionEvent prev = mPrevEvent;
// Focus intenal
PointF mCurrFocusInternal = determineFocalPoint(curr);
PointF mPrevFocusInternal = determineFocalPoint(prev);
// Focus external
// - Prevent skipping of focus delta when a finger is added or removed
boolean mSkipNextMoveEvent = prev.getPointerCount() != curr
.getPointerCount();
mFocusDeltaExternal = mSkipNextMoveEvent ? FOCUS_DELTA_ZERO
: new PointF(mCurrFocusInternal.x - mPrevFocusInternal.x,
mCurrFocusInternal.y - mPrevFocusInternal.y);
// - Don't directly use mFocusInternal (or skipping will occur). Add
// unskipped delta values to mFocusExternal instead.
mFocusExternal.x += mFocusDeltaExternal.x;
mFocusExternal.y += mFocusDeltaExternal.y;
}
/**
* Determine (multi)finger focal point (a.k.a. center point between all
* fingers)
*
* @param e
* @return PointF focal point
*/
private PointF determineFocalPoint(MotionEvent e) {
// Number of fingers on screen
final int pCount = e.getPointerCount();
float x = 0.0f;
float y = 0.0f;
for (int i = 0; i < pCount; i++) {
x += e.getX(i);
y += e.getY(i);
}
return new PointF(x / pCount, y / pCount);
}
public float getFocusX() {
return mFocusExternal.x;
}
public float getFocusY() {
return mFocusExternal.y;
}
public PointF getFocusDelta() {
return mFocusDeltaExternal;
}
public PointF getFocusDelta() {
return focusDeltaExternal;
}
}

View File

@@ -6,19 +6,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
*
* <p>
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,147 +34,147 @@ import android.view.MotionEvent;
*/
public class RotateGestureDetector extends TwoFingerGestureDetector {
/**
* Listener which must be implemented which is used by RotateGestureDetector
* to perform callbacks to any implementing class which is registered to a
* RotateGestureDetector via the constructor.
*
* @see RotateGestureDetector.SimpleOnRotateGestureListener
*/
public interface OnRotateGestureListener {
public boolean onRotate(RotateGestureDetector detector);
/**
* Listener which must be implemented which is used by RotateGestureDetector
* to perform callbacks to any implementing class which is registered to a
* RotateGestureDetector via the constructor.
*
* @see RotateGestureDetector.SimpleOnRotateGestureListener
*/
public interface OnRotateGestureListener {
public boolean onRotate(RotateGestureDetector detector);
public boolean onRotateBegin(RotateGestureDetector detector);
public boolean onRotateBegin(RotateGestureDetector detector);
public void onRotateEnd(RotateGestureDetector detector);
public void onRotateEnd(RotateGestureDetector detector);
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnRotateGestureListener.
*/
public static class SimpleOnRotateGestureListener implements
OnRotateGestureListener {
public boolean onRotate(RotateGestureDetector detector) {
return false;
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnRotateGestureListener.
*/
public static class SimpleOnRotateGestureListener implements
OnRotateGestureListener {
public boolean onRotate(RotateGestureDetector detector) {
return false;
public boolean onRotateBegin(RotateGestureDetector detector) {
return true;
}
public void onRotateEnd(RotateGestureDetector detector) {
// Do nothing, overridden implementation may be used
}
}
private final OnRotateGestureListener listener;
private boolean sloppyGesture;
public RotateGestureDetector(Context context,
OnRotateGestureListener listener) {
super(context);
this.listener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_DOWN:
// At least the second finger is on screen now
resetState(); // In case we missed an UP/CANCEL event
prevEvent = MotionEvent.obtain(event);
timeDelta = 0;
updateStateByEvent(event);
// See if we have a sloppy gesture
sloppyGesture = isSloppyGesture(event);
if (!sloppyGesture) {
// No, start gesture now
gestureInProgress = listener.onRotateBegin(this);
}
break;
case MotionEvent.ACTION_MOVE:
if (!sloppyGesture) {
break;
}
public boolean onRotateBegin(RotateGestureDetector detector) {
return true;
// See if we still have a sloppy gesture
sloppyGesture = isSloppyGesture(event);
if (!sloppyGesture) {
// No, start normal gesture now
gestureInProgress = listener.onRotateBegin(this);
}
public void onRotateEnd(RotateGestureDetector detector) {
// Do nothing, overridden implementation may be used
break;
case MotionEvent.ACTION_POINTER_UP:
if (!sloppyGesture) {
break;
}
break;
}
}
private final OnRotateGestureListener mListener;
private boolean mSloppyGesture;
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_UP:
// Gesture ended but
updateStateByEvent(event);
public RotateGestureDetector(Context context,
OnRotateGestureListener listener) {
super(context);
mListener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_DOWN:
// At least the second finger is on screen now
resetState(); // In case we missed an UP/CANCEL event
mPrevEvent = MotionEvent.obtain(event);
mTimeDelta = 0;
updateStateByEvent(event);
// See if we have a sloppy gesture
mSloppyGesture = isSloppyGesture(event);
if (!mSloppyGesture) {
// No, start gesture now
mGestureInProgress = mListener.onRotateBegin(this);
}
break;
case MotionEvent.ACTION_MOVE:
if (!mSloppyGesture) {
break;
}
// See if we still have a sloppy gesture
mSloppyGesture = isSloppyGesture(event);
if (!mSloppyGesture) {
// No, start normal gesture now
mGestureInProgress = mListener.onRotateBegin(this);
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (!mSloppyGesture) {
break;
}
break;
if (!sloppyGesture) {
listener.onRotateEnd(this);
}
}
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_UP:
// Gesture ended but
updateStateByEvent(event);
resetState();
break;
if (!mSloppyGesture) {
mListener.onRotateEnd(this);
}
resetState();
break;
case MotionEvent.ACTION_CANCEL:
if (!mSloppyGesture) {
mListener.onRotateEnd(this);
}
resetState();
break;
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted.
if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
final boolean updatePrevious = mListener.onRotate(this);
if (updatePrevious) {
mPrevEvent.recycle();
mPrevEvent = MotionEvent.obtain(event);
}
}
break;
case MotionEvent.ACTION_CANCEL:
if (!sloppyGesture) {
listener.onRotateEnd(this);
}
}
@Override
protected void resetState() {
super.resetState();
mSloppyGesture = false;
}
resetState();
break;
/**
* Return the rotation difference from the previous rotate event to the
* current event.
*
* @return The current rotation //difference in degrees.
*/
public float getRotationDegreesDelta() {
double diffRadians = Math.atan2(mPrevFingerDiffY, mPrevFingerDiffX)
- Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX);
return (float) (diffRadians * 180.0 / Math.PI);
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted.
if (currPressure / prevPressure > PRESSURE_THRESHOLD) {
final boolean updatePrevious = listener.onRotate(this);
if (updatePrevious) {
prevEvent.recycle();
prevEvent = MotionEvent.obtain(event);
}
}
break;
}
}
@Override
protected void resetState() {
super.resetState();
sloppyGesture = false;
}
/**
* Return the rotation difference from the previous rotate event to the
* current event.
*
* @return The current rotation //difference in degrees.
*/
public float getRotationDegreesDelta() {
double diffRadians = Math.atan2(prevFingerDiffY, prevFingerDiffX)
- Math.atan2(currFingerDiffY, currFingerDiffX);
return (float) (diffRadians * 180.0 / Math.PI);
}
}

View File

@@ -5,21 +5,21 @@ import android.view.MotionEvent;
/**
* @author Robert Nordan (robert.nordan@norkart.no)
*
* <p>
* Copyright (c) 2013, Norkart AS
*
* <p>
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,179 +35,180 @@ import android.view.MotionEvent;
*/
public class ShoveGestureDetector extends TwoFingerGestureDetector {
/**
* Listener which must be implemented which is used by ShoveGestureDetector
* to perform callbacks to any implementing class which is registered to a
* ShoveGestureDetector via the constructor.
*
* @see ShoveGestureDetector.SimpleOnShoveGestureListener
*/
public interface OnShoveGestureListener {
public boolean onShove(ShoveGestureDetector detector);
/**
* Listener which must be implemented which is used by ShoveGestureDetector
* to perform callbacks to any implementing class which is registered to a
* ShoveGestureDetector via the constructor.
*
* @see ShoveGestureDetector.SimpleOnShoveGestureListener
*/
public interface OnShoveGestureListener {
public boolean onShove(ShoveGestureDetector detector);
public boolean onShoveBegin(ShoveGestureDetector detector);
public boolean onShoveBegin(ShoveGestureDetector detector);
public void onShoveEnd(ShoveGestureDetector detector);
public void onShoveEnd(ShoveGestureDetector detector);
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnShoveGestureListener.
*/
public static class SimpleOnShoveGestureListener implements
OnShoveGestureListener {
public boolean onShove(ShoveGestureDetector detector) {
return false;
}
/**
* Helper class which may be extended and where the methods may be
* implemented. This way it is not necessary to implement all methods of
* OnShoveGestureListener.
*/
public static class SimpleOnShoveGestureListener implements
OnShoveGestureListener {
public boolean onShove(ShoveGestureDetector detector) {
return false;
public boolean onShoveBegin(ShoveGestureDetector detector) {
return true;
}
public void onShoveEnd(ShoveGestureDetector detector) {
// Do nothing, overridden implementation may be used
}
}
private float prevAverageY;
private float currAverageY;
private final OnShoveGestureListener listener;
private boolean sloppyGesture;
public ShoveGestureDetector(Context context, OnShoveGestureListener listener) {
super(context);
this.listener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_DOWN:
// At least the second finger is on screen now
resetState(); // In case we missed an UP/CANCEL event
prevEvent = MotionEvent.obtain(event);
timeDelta = 0;
updateStateByEvent(event);
// See if we have a sloppy gesture
sloppyGesture = isSloppyGesture(event);
if (!sloppyGesture) {
// No, start gesture now
gestureInProgress = listener.onShoveBegin(this);
}
break;
case MotionEvent.ACTION_MOVE:
if (!sloppyGesture) {
break;
}
public boolean onShoveBegin(ShoveGestureDetector detector) {
return true;
// See if we still have a sloppy gesture
sloppyGesture = isSloppyGesture(event);
if (!sloppyGesture) {
// No, start normal gesture now
gestureInProgress = listener.onShoveBegin(this);
}
public void onShoveEnd(ShoveGestureDetector detector) {
// Do nothing, overridden implementation may be used
break;
case MotionEvent.ACTION_POINTER_UP:
if (!sloppyGesture) {
break;
}
break;
}
}
private float mPrevAverageY;
private float mCurrAverageY;
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_UP:
// Gesture ended but
updateStateByEvent(event);
private final OnShoveGestureListener mListener;
private boolean mSloppyGesture;
public ShoveGestureDetector(Context context, OnShoveGestureListener listener) {
super(context);
mListener = listener;
}
@Override
protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_DOWN:
// At least the second finger is on screen now
resetState(); // In case we missed an UP/CANCEL event
mPrevEvent = MotionEvent.obtain(event);
mTimeDelta = 0;
updateStateByEvent(event);
// See if we have a sloppy gesture
mSloppyGesture = isSloppyGesture(event);
if (!mSloppyGesture) {
// No, start gesture now
mGestureInProgress = mListener.onShoveBegin(this);
}
break;
case MotionEvent.ACTION_MOVE:
if (!mSloppyGesture) {
break;
}
// See if we still have a sloppy gesture
mSloppyGesture = isSloppyGesture(event);
if (!mSloppyGesture) {
// No, start normal gesture now
mGestureInProgress = mListener.onShoveBegin(this);
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (!mSloppyGesture) {
break;
}
break;
if (!sloppyGesture) {
listener.onShoveEnd(this);
}
}
@Override
protected void handleInProgressEvent(int actionCode, MotionEvent event) {
switch (actionCode) {
case MotionEvent.ACTION_POINTER_UP:
// Gesture ended but
updateStateByEvent(event);
resetState();
break;
if (!mSloppyGesture) {
mListener.onShoveEnd(this);
}
resetState();
break;
case MotionEvent.ACTION_CANCEL:
if (!mSloppyGesture) {
mListener.onShoveEnd(this);
}
resetState();
break;
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted. Also check that shove is meaningful.
if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD
&& Math.abs(getShovePixelsDelta()) > 0.5f) {
final boolean updatePrevious = mListener.onShove(this);
if (updatePrevious) {
mPrevEvent.recycle();
mPrevEvent = MotionEvent.obtain(event);
}
}
break;
case MotionEvent.ACTION_CANCEL:
if (!sloppyGesture) {
listener.onShoveEnd(this);
}
resetState();
break;
case MotionEvent.ACTION_MOVE:
updateStateByEvent(event);
// Only accept the event if our relative pressure is within
// a certain limit. This can help filter shaky data as a
// finger is lifted. Also check that shove is meaningful.
if (currPressure / prevPressure > PRESSURE_THRESHOLD
&& Math.abs(getShovePixelsDelta()) > 0.5f) {
final boolean updatePrevious = listener.onShove(this);
if (updatePrevious) {
prevEvent.recycle();
prevEvent = MotionEvent.obtain(event);
}
}
break;
}
}
@Override
protected void resetState() {
super.resetState();
sloppyGesture = false;
prevAverageY = 0.0f;
currAverageY = 0.0f;
}
@Override
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
final MotionEvent prev = prevEvent;
float py0 = prev.getY(0);
float py1 = prev.getY(1);
prevAverageY = (py0 + py1) / 2.0f;
float cy0 = curr.getY(0);
float cy1 = curr.getY(1);
currAverageY = (cy0 + cy1) / 2.0f;
}
@Override
protected boolean isSloppyGesture(MotionEvent event) {
boolean sloppy = super.isSloppyGesture(event);
if (sloppy) {
return true;
}
@Override
protected void resetState() {
super.resetState();
mSloppyGesture = false;
mPrevAverageY = 0.0f;
mCurrAverageY = 0.0f;
}
// If it's not traditionally sloppy, we check if the angle between
// fingers
// is acceptable.
double angle = Math.abs(Math.atan2(currFingerDiffY, currFingerDiffX));
// about 20 degrees, left or right
return !((0.0f < angle && angle < 0.35f) || 2.79f < angle
&& angle < Math.PI);
}
@Override
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
final MotionEvent prev = mPrevEvent;
float py0 = prev.getY(0);
float py1 = prev.getY(1);
mPrevAverageY = (py0 + py1) / 2.0f;
float cy0 = curr.getY(0);
float cy1 = curr.getY(1);
mCurrAverageY = (cy0 + cy1) / 2.0f;
}
@Override
protected boolean isSloppyGesture(MotionEvent event) {
boolean sloppy = super.isSloppyGesture(event);
if (sloppy)
return true;
// If it's not traditionally sloppy, we check if the angle between
// fingers
// is acceptable.
double angle = Math.abs(Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX));
// about 20 degrees, left or right
return !((0.0f < angle && angle < 0.35f) || 2.79f < angle
&& angle < Math.PI);
}
/**
* Return the distance in pixels from the previous shove event to the
* current event.
*
* @return The current distance in pixels.
*/
public float getShovePixelsDelta() {
return mCurrAverageY - mPrevAverageY;
}
/**
* Return the distance in pixels from the previous shove event to the
* current event.
*
* @return The current distance in pixels.
*/
public float getShovePixelsDelta() {
return currAverageY - prevAverageY;
}
}

View File

@@ -9,19 +9,19 @@ import android.view.ViewConfiguration;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
*
* <p>
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -37,189 +37,189 @@ import android.view.ViewConfiguration;
*/
public abstract class TwoFingerGestureDetector extends BaseGestureDetector {
private final float mEdgeSlop;
private final float edgeSlop;
protected float mPrevFingerDiffX;
protected float mPrevFingerDiffY;
protected float mCurrFingerDiffX;
protected float mCurrFingerDiffY;
protected float prevFingerDiffX;
protected float prevFingerDiffY;
protected float currFingerDiffX;
protected float currFingerDiffY;
private float mCurrLen;
private float mPrevLen;
private float currLen;
private float prevLen;
private PointF mFocus;
private PointF focus;
public TwoFingerGestureDetector(Context context) {
super(context);
public TwoFingerGestureDetector(Context context) {
super(context);
ViewConfiguration config = ViewConfiguration.get(context);
ViewConfiguration config = ViewConfiguration.get(context);
// We divide edge slop by 2 to make rotation gesture happen more easily #6870
mEdgeSlop = config.getScaledEdgeSlop() / 2;
// We divide edge slop by 2 to make rotation gesture happen more easily #6870
edgeSlop = config.getScaledEdgeSlop() / 2;
}
@Override
protected abstract void handleStartProgressEvent(int actionCode,
MotionEvent event);
@Override
protected abstract void handleInProgressEvent(int actionCode,
MotionEvent event);
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
final MotionEvent prev = prevEvent;
currLen = -1;
prevLen = -1;
// Previous
final float px0 = prev.getX(0);
final float py0 = prev.getY(0);
final float px1 = prev.getX(1);
final float py1 = prev.getY(1);
final float pvx = px1 - px0;
final float pvy = py1 - py0;
prevFingerDiffX = pvx;
prevFingerDiffY = pvy;
// Current
final float cx0 = curr.getX(0);
final float cy0 = curr.getY(0);
final float cx1 = curr.getX(1);
final float cy1 = curr.getY(1);
final float cvx = cx1 - cx0;
final float cvy = cy1 - cy0;
currFingerDiffX = cvx;
currFingerDiffY = cvy;
focus = determineFocalPoint(curr);
}
/**
* Return the current distance between the two pointers forming the gesture
* in progress.
*
* @return Distance between pointers in pixels.
*/
public float getCurrentSpan() {
if (currLen == -1) {
final float cvx = currFingerDiffX;
final float cvy = currFingerDiffY;
currLen = (float) Math.sqrt(cvx * cvx + cvy * cvy);
}
return currLen;
}
/**
* Return the previous distance between the two pointers forming the gesture
* in progress.
*
* @return Previous distance between pointers in pixels.
*/
public float getPreviousSpan() {
if (prevLen == -1) {
final float pvx = prevFingerDiffX;
final float pvy = prevFingerDiffY;
prevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy);
}
return prevLen;
}
/**
* MotionEvent has no getRawX(int) method; simulate it pending future API
* approval.
*
* @param event Motion Event
* @param pointerIndex Pointer Index
* @return Raw x value or 0
*/
protected static float getRawX(MotionEvent event, int pointerIndex) {
float offset = event.getRawX() - event.getX();
if (pointerIndex < event.getPointerCount()) {
return event.getX(pointerIndex) + offset;
}
return 0.0f;
}
/**
* MotionEvent has no getRawY(int) method; simulate it pending future API
* approval.
*
* @param event Motion Event
* @param pointerIndex Pointer Index
* @return Raw y value or 0
*/
protected static float getRawY(MotionEvent event, int pointerIndex) {
float offset = event.getRawY() - event.getY();
if (pointerIndex < event.getPointerCount()) {
return event.getY(pointerIndex) + offset;
}
return 0.0f;
}
/**
* Check if we have a sloppy gesture. Sloppy gestures can happen if the edge
* of the user's hand is touching the screen, for example.
*
* @param event Motion Event
* @return {@code true} if is sloppy gesture, {@code false} if not
*/
protected boolean isSloppyGesture(MotionEvent event) {
// As orientation can change, query the metrics in touch down
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
float rightSlopEdge = metrics.widthPixels - edgeSlop;
float bottomSlopEdge = metrics.heightPixels - edgeSlop;
final float edgeSlop = this.edgeSlop;
final float x0 = event.getRawX();
final float y0 = event.getRawY();
final float x1 = getRawX(event, 1);
final float y1 = getRawY(event, 1);
boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlopEdge
|| y0 > bottomSlopEdge;
boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlopEdge
|| y1 > bottomSlopEdge;
if (p0sloppy && p1sloppy) {
return true;
} else if (p0sloppy) {
return true;
} else if (p1sloppy) {
return true;
}
return false;
}
/**
* Determine (multi)finger focal point (a.k.a. center point between all
* fingers)
*
* @param motionEvent Motion Event
* @return PointF focal point
*/
public static PointF determineFocalPoint(MotionEvent motionEvent) {
// Number of fingers on screen
final int pCount = motionEvent.getPointerCount();
float x = 0.0f;
float y = 0.0f;
for (int i = 0; i < pCount; i++) {
x += motionEvent.getX(i);
y += motionEvent.getY(i);
}
@Override
protected abstract void handleStartProgressEvent(int actionCode,
MotionEvent event);
return new PointF(x / pCount, y / pCount);
}
@Override
protected abstract void handleInProgressEvent(int actionCode,
MotionEvent event);
public float getFocusX() {
return focus.x;
}
protected void updateStateByEvent(MotionEvent curr) {
super.updateStateByEvent(curr);
final MotionEvent prev = mPrevEvent;
mCurrLen = -1;
mPrevLen = -1;
// Previous
final float px0 = prev.getX(0);
final float py0 = prev.getY(0);
final float px1 = prev.getX(1);
final float py1 = prev.getY(1);
final float pvx = px1 - px0;
final float pvy = py1 - py0;
mPrevFingerDiffX = pvx;
mPrevFingerDiffY = pvy;
// Current
final float cx0 = curr.getX(0);
final float cy0 = curr.getY(0);
final float cx1 = curr.getX(1);
final float cy1 = curr.getY(1);
final float cvx = cx1 - cx0;
final float cvy = cy1 - cy0;
mCurrFingerDiffX = cvx;
mCurrFingerDiffY = cvy;
mFocus = determineFocalPoint(curr);
}
/**
* Return the current distance between the two pointers forming the gesture
* in progress.
*
* @return Distance between pointers in pixels.
*/
public float getCurrentSpan() {
if (mCurrLen == -1) {
final float cvx = mCurrFingerDiffX;
final float cvy = mCurrFingerDiffY;
mCurrLen = (float) Math.sqrt(cvx * cvx + cvy * cvy);
}
return mCurrLen;
}
/**
* Return the previous distance between the two pointers forming the gesture
* in progress.
*
* @return Previous distance between pointers in pixels.
*/
public float getPreviousSpan() {
if (mPrevLen == -1) {
final float pvx = mPrevFingerDiffX;
final float pvy = mPrevFingerDiffY;
mPrevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy);
}
return mPrevLen;
}
/**
* MotionEvent has no getRawX(int) method; simulate it pending future API
* approval.
*
* @param event Motion Event
* @param pointerIndex Pointer Index
* @return Raw x value or 0
*/
protected static float getRawX(MotionEvent event, int pointerIndex) {
float offset = event.getRawX() - event.getX();
if (pointerIndex < event.getPointerCount()) {
return event.getX(pointerIndex) + offset;
}
return 0.0f;
}
/**
* MotionEvent has no getRawY(int) method; simulate it pending future API
* approval.
*
* @param event Motion Event
* @param pointerIndex Pointer Index
* @return Raw y value or 0
*/
protected static float getRawY(MotionEvent event, int pointerIndex) {
float offset = event.getRawY() - event.getY();
if (pointerIndex < event.getPointerCount()) {
return event.getY(pointerIndex) + offset;
}
return 0.0f;
}
/**
* Check if we have a sloppy gesture. Sloppy gestures can happen if the edge
* of the user's hand is touching the screen, for example.
*
* @param event Motion Event
* @return {@code true} if is sloppy gesture, {@code false} if not
*/
protected boolean isSloppyGesture(MotionEvent event) {
// As orientation can change, query the metrics in touch down
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
float mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
float mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
final float edgeSlop = mEdgeSlop;
final float x0 = event.getRawX();
final float y0 = event.getRawY();
final float x1 = getRawX(event, 1);
final float y1 = getRawY(event, 1);
boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > mRightSlopEdge
|| y0 > mBottomSlopEdge;
boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > mRightSlopEdge
|| y1 > mBottomSlopEdge;
if (p0sloppy && p1sloppy) {
return true;
} else if (p0sloppy) {
return true;
} else if (p1sloppy) {
return true;
}
return false;
}
/**
* Determine (multi)finger focal point (a.k.a. center point between all
* fingers)
*
* @param e Motion Event
* @return PointF focal point
*/
public static PointF determineFocalPoint(MotionEvent e) {
// Number of fingers on screen
final int pCount = e.getPointerCount();
float x = 0.0f;
float y = 0.0f;
for (int i = 0; i < pCount; i++) {
x += e.getX(i);
y += e.getY(i);
}
return new PointF(x / pCount, y / pCount);
}
public float getFocusX() {
return mFocus.x;
}
public float getFocusY() {
return mFocus.y;
}
public float getFocusY() {
return focus.y;
}
}

View File

@@ -13,119 +13,121 @@ import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
public class MapboxAccountManager {
private static MapboxAccountManager mapboxAccountManager = null;
private static MapboxAccountManager mapboxAccountManager = null;
private final String accessToken;
private final Context applicationContext;
private final String accessToken;
private final Context applicationContext;
private Boolean connected = null;
private Boolean connected = null;
/**
* MapboxAccountManager should NOT be instantiated directly.
* Use @see MapboxAccountManager#getInstance() instead.
*
* @param applicationContext Context used to get ApplicationContext
* @param accessToken Mapbox Access Token
*/
private MapboxAccountManager(Context applicationContext, String accessToken) {
super();
this.applicationContext = applicationContext.getApplicationContext();
this.accessToken = accessToken;
/**
* MapboxAccountManager should NOT be instantiated directly.
* Use @see MapboxAccountManager#getInstance() instead.
*
* @param applicationContext Context used to get ApplicationContext
* @param accessToken Mapbox Access Token
*/
private MapboxAccountManager(Context applicationContext, String accessToken) {
super();
this.applicationContext = applicationContext.getApplicationContext();
this.accessToken = accessToken;
}
/**
* Primary entry point to Mapbox for implementing developers.
* Must be configured in either Application.onCreate() or Launch Activity.onCreate()
*
* @param context Context used to get Application Context
* @param accessToken Mapbox Access Token. You can get one on the Mapbox Web site.
* @return MapboxAccountManager instance for app
*/
public static MapboxAccountManager start(Context context, String accessToken) {
if (mapboxAccountManager == null) {
//Create a new account manager
mapboxAccountManager = new MapboxAccountManager(context, accessToken);
//Initialize the event manager
MapboxEventManager.getMapboxEventManager().initialize(context, accessToken);
//Register a receiver to listen for connectivity updates
ConnectivityReceiver.instance(context);
}
/**
* Primary entry point to Mapbox for implementing developers.
* Must be configured in either Application.onCreate() or Launch Activity.onCreate()
*
* @param context Context used to get Application Context
* @param accessToken Mapbox Access Token. You can get one on the Mapbox Web site.
* @return MapboxAccountManager instance for app
*/
public static MapboxAccountManager start(Context context, String accessToken) {
if (mapboxAccountManager == null) {
//Create a new account manager
mapboxAccountManager = new MapboxAccountManager(context, accessToken);
return mapboxAccountManager;
}
//Initialize the event manager
MapboxEventManager.getMapboxEventManager().initialize(context, accessToken);
//Register a receiver to listen for connectivity updates
ConnectivityReceiver.instance(context);
}
return mapboxAccountManager;
/**
* Internal Use Only
* Get an instance of MapboxAccountManager configured with the app's Access Token
*
* @return MapboxAccountManager instance for app. May be NULL if not configured yet.
*/
public static MapboxAccountManager getInstance() {
if (mapboxAccountManager == null) {
throw new MapboxAccountManagerNotStartedException();
}
/**
* Internal Use Only
* Get an instance of MapboxAccountManager configured with the app's Access Token
*
* @return MapboxAccountManager instance for app. May be NULL if not configured yet.
*/
public static MapboxAccountManager getInstance() {
if (mapboxAccountManager == null) {
throw new MapboxAccountManagerNotStartedException();
}
return mapboxAccountManager;
}
return mapboxAccountManager;
/**
* Access Token for this application.
*
* @return Mapbox Access Token
*/
public String getAccessToken() {
return accessToken;
}
/**
* Runtime validation of Access Token.
*
* @param accessToken Access Token to check
* @throws InvalidAccessTokenException the exception thrown
*/
public static void validateAccessToken(String accessToken) throws InvalidAccessTokenException {
if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.")
&& !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) {
throw new InvalidAccessTokenException();
}
}
/**
* Manually sets the connectivity state of the app. This is useful for apps that control their
* own connectivity state and want to bypass any checks to the ConnectivityManager.
*
* @param connected flag to determine the connectivity state, true for connected, false for
* disconnected, null for ConnectivityManager to determine.
*/
public void setConnected(Boolean connected) {
// Connectivity state overridden by app
this.connected = connected;
}
/**
* Determines whether we have an Internet connection available. Please do not rely on this
* method in your apps, this method is used internally by the SDK.
*
* @return true if there is an Internet connection, false otherwise
*/
public Boolean isConnected() {
if (connected != null) {
// Connectivity state overridden by app
return connected;
}
/**
* Access Token for this application.
*
* @return Mapbox Access Token
*/
public String getAccessToken() {
return accessToken;
}
ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
/**
* Runtime validation of Access Token.
*
* @param accessToken Access Token to check
* @throws InvalidAccessTokenException the exception thrown
*/
public static void validateAccessToken(String accessToken) throws InvalidAccessTokenException {
if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.") && !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) {
throw new InvalidAccessTokenException();
}
}
/**
* Manually sets the connectivity state of the app. This is useful for apps that control their
* own connectivity state and want to bypass any checks to the ConnectivityManager.
*
* @param connected flag to determine the connectivity state, true for connected, false for
* disconnected, null for ConnectivityManager to determine.
*/
public void setConnected(Boolean connected) {
// Connectivity state overridden by app
this.connected = connected;
}
/**
* Determines whether we have an Internet connection available. Please do not rely on this
* method in your apps, this method is used internally by the SDK.
*
* @return true if there is an Internet connection, false otherwise
*/
public Boolean isConnected() {
if (connected != null) {
// Connectivity state overridden by app
return connected;
}
ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
/**
* Not public API
* @return the Application Context
*/
public Context getApplicationContext() {
return applicationContext;
}
/**
* Not public API
*
* @return the Application Context
*/
public Context getApplicationContext() {
return applicationContext;
}
}

View File

@@ -15,123 +15,127 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public abstract class Annotation implements Comparable<Annotation> {
/**
* <p>
* The annotation id
* </p>
* Internal C++ id is stored as unsigned int.
*/
private long id = -1; // -1 unless added to a MapView
protected MapboxMap mapboxMap;
protected MapView mapView;
/**
* <p>
* The annotation id
* </p>
* Internal C++ id is stored as unsigned int.
*/
private long id = -1; // -1 unless added to a MapView
protected MapboxMap mapboxMap;
protected MapView mapView;
protected Annotation() {
}
protected Annotation() {
}
/**
* <p>
* Gets the annotation's unique ID.
* </p>
* This ID is unique for a MapView instance and is suitable for associating your own extra
* data with.
*
* @return the assigned id.
*/
public long getId() {
return id;
}
/**
* <p>
* Gets the annotation's unique ID.
* </p>
* This ID is unique for a MapView instance and is suitable for associating your own extra
* data with.
*
* @return the assigned id.
*/
public long getId() {
return id;
}
/**
* Do not use this method, used internally by the SDK.
*/
public void remove() {
if (mapboxMap == null) {
return;
}
mapboxMap.removeAnnotation(this);
/**
* Do not use this method, used internally by the SDK.
*/
public void remove() {
if (mapboxMap == null) {
return;
}
mapboxMap.removeAnnotation(this);
}
/**
* Do not use this method, used internally by the SDK.
*
* @param id the assigned id
*/
public void setId(long id) {
this.id = id;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param id the assigned id
*/
public void setId(long id) {
this.id = id;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param mapboxMap the hosting mapbox map
*/
public void setMapboxMap(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param mapboxMap the hosting mapbox map
*/
public void setMapboxMap(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
}
/**
* Gets the hosting mapbox map.
*
* @return the MapboxMap
*/
protected MapboxMap getMapboxMap() {
return mapboxMap;
}
/**
* Gets the hosting mapbox map.
*
* @return the MapboxMap
*/
protected MapboxMap getMapboxMap() {
return mapboxMap;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param mapView the hosting map view
*/
public void setMapView(MapView mapView) {
this.mapView = mapView;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param mapView the hosting map view
*/
public void setMapView(MapView mapView) {
this.mapView = mapView;
}
/**
* Gets the hosting map view.
*
* @return The MapView
*/
protected MapView getMapView() {
return mapView;
}
/**
* Gets the hosting map view.
*
* @return The MapView
*/
protected MapView getMapView() {
return mapView;
}
@Override
public int compareTo(@NonNull Annotation annotation) {
if (id < annotation.getId()) {
return 1;
} else if (id > annotation.getId()) {
return -1;
}
return 0;
@Override
public int compareTo(@NonNull Annotation annotation) {
if (id < annotation.getId()) {
return 1;
} else if (id > annotation.getId()) {
return -1;
}
return 0;
}
/**
* Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
* determines if their color, alpha, width, and vertices match.
*
* @param o Another {@link PolylineOptions} to compare with this object.
* @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !(o instanceof Annotation)) return false;
Annotation that = (Annotation) o;
return id == that.getId();
/**
* Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
* determines if their color, alpha, width, and vertices match.
*
* @param object Another {@link PolylineOptions} to compare with this object.
* @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || !(object instanceof Annotation)) {
return false;
}
Annotation that = (Annotation) object;
return id == that.getId();
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
return (int) (getId() ^ (getId() >>> 32));
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
return (int) (getId() ^ (getId() >>> 32));
}
}

View File

@@ -6,7 +6,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
/**
* Abstract builder class for composing custom Marker objects.
*
* <p>
* Extending this class requires implementing Parceable interface.
*
* @param <U> Type of the marker to be composed
@@ -14,107 +14,107 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
*/
public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOptions<U, T>> implements Parcelable {
protected LatLng position;
protected String snippet;
protected String title;
protected Icon icon;
protected LatLng position;
protected String snippet;
protected String title;
protected Icon icon;
/**
* Set the geographical location of the Marker.
*
* @param position the location to position the {@link Marker}.
* @return the object for which the method was called.
*/
public T position(LatLng position) {
this.position = position;
return getThis();
}
/**
* Set the geographical location of the Marker.
*
* @param position the location to position the {@link Marker}.
* @return the object for which the method was called.
*/
public T position(LatLng position) {
this.position = position;
return getThis();
}
/**
* Set the snippet of the Marker.
*
* @param snippet the snippet of the {@link Marker}.
* @return the object for which the method was called.
*/
public T snippet(String snippet) {
this.snippet = snippet;
return getThis();
}
/**
* Set the snippet of the Marker.
*
* @param snippet the snippet of the {@link Marker}.
* @return the object for which the method was called.
*/
public T snippet(String snippet) {
this.snippet = snippet;
return getThis();
}
/**
* Set the title of the Marker.
*
* @param title the title of the {@link Marker}.
* @return the object for which the method was called.
*/
public T title(String title) {
this.title = title;
return getThis();
}
/**
* Set the title of the Marker.
*
* @param title the title of the {@link Marker}.
* @return the object for which the method was called.
*/
public T title(String title) {
this.title = title;
return getThis();
}
/**
* Set the icon of the Marker.
*
* @param icon the icon of the {@link Marker}.
* @return the object for which the method was called.
*/
public T icon(Icon icon) {
this.icon = icon;
return getThis();
}
/**
* Set the icon of the Marker.
*
* @param icon the icon of the {@link Marker}.
* @return the object for which the method was called.
*/
public T icon(Icon icon) {
this.icon = icon;
return getThis();
}
/**
* Set the icon of the Marker.
*
* @param icon the icon of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setIcon(Icon icon) {
return icon(icon);
}
/**
* Set the icon of the Marker.
*
* @param icon the icon of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setIcon(Icon icon) {
return icon(icon);
}
/**
* Set the geographical location of the Marker.
*
* @param position the location to position the {@link Marker}.
* @return the object for which the method was called.
*/
public T setPosition(LatLng position) {
return position(position);
}
/**
* Set the geographical location of the Marker.
*
* @param position the location to position the {@link Marker}.
* @return the object for which the method was called.
*/
public T setPosition(LatLng position) {
return position(position);
}
/**
* Set the snippet of the Marker.
*
* @param snippet the snippet of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setSnippet(String snippet) {
return snippet(snippet);
}
/**
* Set the snippet of the Marker.
*
* @param snippet the snippet of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setSnippet(String snippet) {
return snippet(snippet);
}
/**
* Set the title of the Marker.
*
* @param title the title of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setTitle(String title) {
return title(title);
}
/**
* Set the title of the Marker.
*
* @param title the title of the {@link Marker}.
* @return the object for which the method was called.
*/
public T setTitle(String title) {
return title(title);
}
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which the this method was called.
*/
public abstract T getThis();
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which the this method was called.
*/
public abstract T getThis();
/**
* Get the Marker.
*
* @return the Marker created from this builder.
*/
public abstract U getMarker();
/**
* Get the Marker.
*
* @return the Marker created from this builder.
*/
public abstract U getMarker();
}

View File

@@ -15,267 +15,268 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
* @param <U> Type of the marker view to be composed.
* @param <T> Type of the builder to be used for composing.
*/
public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends BaseMarkerViewOptions<U, T>> implements Parcelable {
public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends BaseMarkerViewOptions<U, T>>
implements Parcelable {
protected LatLng position;
protected String snippet;
protected String title;
protected Icon icon;
protected boolean flat;
protected float anchorU = 0.5f;
protected float anchorV = 1f;
protected float infoWindowAnchorU = 0.5f;
protected float infoWindowAnchorV = 0.0f;
protected float rotation;
protected boolean visible = true;
protected boolean selected;
protected float alpha = 1.0f;
protected LatLng position;
protected String snippet;
protected String title;
protected Icon icon;
protected boolean flat;
protected float anchorU = 0.5f;
protected float anchorV = 1f;
protected float infoWindowAnchorU = 0.5f;
protected float infoWindowAnchorV = 0.0f;
protected float rotation;
protected boolean visible = true;
protected boolean selected;
protected float alpha = 1.0f;
/**
* Default constructor
*/
public BaseMarkerViewOptions() {
/**
* Default constructor
*/
public BaseMarkerViewOptions() {
}
/**
* Set the geographical location of the MarkerView.
*
* @param position the location to position the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T position(@NonNull LatLng position) {
this.position = position;
return getThis();
}
/**
* Set the snippet of the MarkerView.
*
* @param snippet the snippet of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T snippet(String snippet) {
this.snippet = snippet;
return getThis();
}
/**
* Set the title of the MarkerView.
*
* @param title the title of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T title(String title) {
this.title = title;
return getThis();
}
/**
* Set the icon of the MarkerView.
*
* @param icon the icon of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T icon(Icon icon) {
this.icon = icon;
return getThis();
}
/**
* Set the flat state of the MarkerView.
*
* @param flat the flat state of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T flat(boolean flat) {
this.flat = flat;
return getThis();
}
/**
* Set the anchor of the {@link MarkerView}.
*
* @param u the u-value.
* @param v the v-value.
* @return the object for which the method was called.
*/
public T anchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
return getThis();
}
/**
* Set the InfoWindow anchor of the {@link MarkerView}.
*
* @param u the u-value.
* @param v the v-values.
* @return the object for which the method was called.
*/
public T infoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
return getThis();
}
/**
* Set the rotation of the {@link MarkerView}.
*
* @param rotation the rotation value.
* @return the object for which the method was called.
*/
public T rotation(float rotation) {
this.rotation = rotation;
while (this.rotation > 360) {
this.rotation -= 360;
}
/**
* Set the geographical location of the MarkerView.
*
* @param position the location to position the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T position(@NonNull LatLng position) {
this.position = position;
return getThis();
while (this.rotation < 0) {
this.rotation += 360;
}
return getThis();
}
/**
* Set the snippet of the MarkerView.
*
* @param snippet the snippet of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T snippet(String snippet) {
this.snippet = snippet;
return getThis();
}
/**
* Set the visibility state of the {@link MarkerView}.
*
* @param visible the visible state.
* @return the object for which the method was called.
*/
public T visible(boolean visible) {
this.visible = visible;
return getThis();
}
/**
* Set the title of the MarkerView.
*
* @param title the title of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T title(String title) {
this.title = title;
return getThis();
}
/**
* Set the alpha of the {@link MarkerView}.
*
* @param alpha the alpha value.
* @return the object for which the method was called.
*/
public T alpha(float alpha) {
this.alpha = alpha;
return getThis();
}
/**
* Set the icon of the MarkerView.
*
* @param icon the icon of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T icon(Icon icon) {
this.icon = icon;
return getThis();
}
/**
* Get the geographical location of the {@link MarkerView}.
*
* @return the geographical location.
*/
public LatLng getPosition() {
return position;
}
/**
* Set the flat state of the MarkerView.
*
* @param flat the flat state of the {@link MarkerView}.
* @return the object for which the method was called.
*/
public T flat(boolean flat) {
this.flat = flat;
return getThis();
}
/**
* Get the snippet of the {@link MarkerView}.
*
* @return the snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Set the anchor of the {@link MarkerView}.
*
* @param u the u-value.
* @param v the v-value.
* @return the object for which the method was called.
*/
public T anchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
return getThis();
}
/**
* Get the title of the {@link MarkerView}.
*
* @return the title.
*/
public String getTitle() {
return title;
}
/**
* Set the InfoWindow anchor of the {@link MarkerView}.
*
* @param u the u-value.
* @param v the v-values.
* @return the object for which the method was called.
*/
public T infoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
return getThis();
}
/**
* Get the icon of the {@link MarkerView}.
*
* @return the icon.
*/
public Icon getIcon() {
return icon;
}
/**
* Set the rotation of the {@link MarkerView}.
*
* @param rotation the rotation value.
* @return the object for which the method was called.
*/
public T rotation(float rotation) {
this.rotation = rotation;
while (this.rotation > 360) {
this.rotation -= 360;
}
while (this.rotation < 0) {
this.rotation += 360;
}
return getThis();
}
/**
* Get the flat state of the {@link MarkerView}.
*
* @return the flat state.
*/
public boolean isFlat() {
return flat;
}
/**
* Set the visibility state of the {@link MarkerView}.
*
* @param visible the visible state.
* @return the object for which the method was called.
*/
public T visible(boolean visible) {
this.visible = visible;
return getThis();
}
/**
* Get the u-value of the {@link MarkerView} anchor.
*
* @return the u-value.
*/
public float getAnchorU() {
return anchorU;
}
/**
* Set the alpha of the {@link MarkerView}.
*
* @param alpha the alpha value.
* @return the object for which the method was called.
*/
public T alpha(float alpha) {
this.alpha = alpha;
return getThis();
}
/**
* Get the v-value of the {@link MarkerView} anchor.
*
* @return the v-value.
*/
public float getAnchorV() {
return anchorV;
}
/**
* Get the geographical location of the {@link MarkerView}.
*
* @return the geographical location.
*/
public LatLng getPosition() {
return position;
}
/**
* Get the u-value of the MarkerView InfoWindow anchor.
*
* @return the u-value.
*/
public float getInfoWindowAnchorU() {
return infoWindowAnchorU;
}
/**
* Get the snippet of the {@link MarkerView}.
*
* @return the snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Get the v-value of the MarkerView InfoWindow anchor.
*
* @return the v-value.
*/
public float getInfoWindowAnchorV() {
return infoWindowAnchorV;
}
/**
* Get the title of the {@link MarkerView}.
*
* @return the title.
*/
public String getTitle() {
return title;
}
/**
* Get the rotation of the MarkerView.
*
* @return the rotation value.
*/
public float getRotation() {
return rotation;
}
/**
* Get the icon of the {@link MarkerView}.
*
* @return the icon.
*/
public Icon getIcon() {
return icon;
}
/**
* Get the visibility state of the MarkerView.
*
* @return the visibility state.
*/
public boolean isVisible() {
return visible;
}
/**
* Get the flat state of the {@link MarkerView}.
*
* @return the flat state.
*/
public boolean isFlat() {
return flat;
}
/**
* Get the alpha of the MarkerView.
*
* @return the alpha value.
*/
public float getAlpha() {
return alpha;
}
/**
* Get the u-value of the {@link MarkerView} anchor.
*
* @return the u-value.
*/
public float getAnchorU() {
return anchorU;
}
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which the this method was called.
*/
public abstract T getThis();
/**
* Get the v-value of the {@link MarkerView} anchor.
*
* @return the v-value.
*/
public float getAnchorV() {
return anchorV;
}
/**
* Get the u-value of the MarkerView InfoWindow anchor.
*
* @return the u-value.
*/
public float getInfoWindowAnchorU() {
return infoWindowAnchorU;
}
/**
* Get the v-value of the MarkerView InfoWindow anchor.
*
* @return the v-value.
*/
public float getInfoWindowAnchorV() {
return infoWindowAnchorV;
}
/**
* Get the rotation of the MarkerView.
*
* @return the rotation value.
*/
public float getRotation() {
return rotation;
}
/**
* Get the visibility state of the MarkerView.
*
* @return the visibility state.
*/
public boolean isVisible() {
return visible;
}
/**
* Get the alpha of the MarkerView.
*
* @return the alpha value.
*/
public float getAlpha() {
return alpha;
}
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which the this method was called.
*/
public abstract T getThis();
/**
* Get the MarkerView.
*
* @return the MarkerView created from this builder.
*/
public abstract U getMarker();
/**
* Get the MarkerView.
*
* @return the MarkerView created from this builder.
*/
public abstract U getMarker();
}

View File

@@ -10,67 +10,73 @@ import com.mapbox.mapboxsdk.maps.MapView;
* @see Marker
*/
public class Icon {
private Bitmap mBitmap;
private String mId;
private Bitmap mBitmap;
private String mId;
Icon(String id, Bitmap bitmap) {
mId = id;
mBitmap = bitmap;
Icon(String id, Bitmap bitmap) {
mId = id;
mBitmap = bitmap;
}
/**
* {@link String} identifier for this {@link Icon}.
*
* @return {@link String} identifier for this {@link Icon}.
*/
public String getId() {
return mId;
}
/**
* Get the {@link Bitmap} being used for this {@link Icon}.
*
* @return The {@link Bitmap} being used for the {@link Icon}.
*/
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Compares this {@link Icon} object with another {@link Icon} and determines if they match.
*
* @param object Another {@link Icon} to compare with this object.
* @return True if the {@link Icon} being passed in matches this {@link Icon} object. Else,
* false.
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
/**
* {@link String} identifier for this {@link Icon}.
*
* @return {@link String} identifier for this {@link Icon}.
*/
public String getId() {
return mId;
Icon icon = (Icon) object;
if (!mBitmap.equals(icon.mBitmap)) {
return false;
}
return mId.equals(icon.mId);
}
/**
* Get the {@link Bitmap} being used for this {@link Icon}.
*
* @return The {@link Bitmap} being used for the {@link Icon}.
*/
public Bitmap getBitmap() {
return mBitmap;
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 0;
if (mBitmap != null) {
result = mBitmap.hashCode();
}
/**
* Compares this {@link Icon} object with another {@link Icon} and determines if they match.
*
* @param o Another {@link Icon} to compare with this object.
* @return True if the {@link Icon} being passed in matches this {@link Icon} object. Else,
* false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Icon icon = (Icon) o;
if (!mBitmap.equals(icon.mBitmap)) return false;
return mId.equals(icon.mId);
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 0;
if (mBitmap != null) {
result = mBitmap.hashCode();
}
if (mId != null) {
result = 31 * result + mId.hashCode();
}
return result;
if (mId != null) {
result = 31 * result + mId.hashCode();
}
return result;
}
}

View File

@@ -29,205 +29,207 @@ import java.io.InputStream;
*/
public final class IconFactory {
private static final String ICON_ID_PREFIX = "com.mapbox.icons.icon_";
public static final Bitmap ICON_MARKERVIEW_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
public static final String ICON_MARKERVIEW_ID = ICON_ID_PREFIX + "marker_view";
private static final String ICON_ID_PREFIX = "com.mapbox.icons.icon_";
public static final Bitmap ICON_MARKERVIEW_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
public static final String ICON_MARKERVIEW_ID = ICON_ID_PREFIX + "marker_view";
private Context mContext;
private static IconFactory sInstance;
private Icon mDefaultMarker;
private Icon mDefaultMarkerView;
private BitmapFactory.Options mOptions;
private Context mContext;
private static IconFactory sInstance;
private Icon mDefaultMarker;
private Icon mDefaultMarkerView;
private BitmapFactory.Options mOptions;
private int mNextId = 0;
private int mNextId = 0;
public static synchronized IconFactory getInstance(@NonNull Context context) {
if (sInstance == null) {
sInstance = new IconFactory(context.getApplicationContext());
}
return sInstance;
public static synchronized IconFactory getInstance(@NonNull Context context) {
if (sInstance == null) {
sInstance = new IconFactory(context.getApplicationContext());
}
return sInstance;
}
private IconFactory(@NonNull Context context) {
mContext = context;
DisplayMetrics realMetrics = null;
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
realMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getRealMetrics(realMetrics);
}
wm.getDefaultDisplay().getMetrics(metrics);
mOptions = new BitmapFactory.Options();
mOptions.inScaled = true;
mOptions.inDensity = DisplayMetrics.DENSITY_DEFAULT;
mOptions.inTargetDensity = metrics.densityDpi;
if (realMetrics != null) {
mOptions.inScreenDensity = realMetrics.densityDpi;
}
}
/**
* Creates an {@link Icon} from a given Bitmap image.
*
* @param bitmap image used for creating the Icon.
* @return The {@link Icon} using the given Bitmap image.
*/
public Icon fromBitmap(@NonNull Bitmap bitmap) {
if (mNextId < 0) {
throw new TooManyIconsException();
}
String id = ICON_ID_PREFIX + ++mNextId;
return new Icon(id, bitmap);
}
/**
* Create an {@link Icon} from a given {@link Drawable}.
*
* @param drawable A {@link Drawable} object used for creating the {@link Icon}.
* @return {@link Icon} with the provided {@link Drawable}.
*/
public Icon fromDrawable(@NonNull Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
return fromDrawable(drawable, width, height);
}
/**
* Create an {@link Icon} from a given {@link Drawable}.
*
* @param drawable A {@link Drawable} object used for creating the {@link Icon}.
* @param width An integer greater then zero defining the {@link Icon} width.
* @param height An integer greater then zero defining the {@link Icon} height.
* @return {@link Icon} with the provided {@link Drawable}.
*/
public Icon fromDrawable(@NonNull Drawable drawable, int width, int height) {
if ((width < 0) || (height < 0)) {
return null;
}
private IconFactory(@NonNull Context context) {
mContext = context;
DisplayMetrics realMetrics = null;
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Rect temp = drawable.getBounds();
Rect bounds = new Rect(0, 0, width, height);
drawable.setBounds(bounds);
drawable.draw(canvas);
drawable.setBounds(temp);
return fromBitmap(bitmap);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
realMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getRealMetrics(realMetrics);
}
wm.getDefaultDisplay().getMetrics(metrics);
/**
* Create an {@link Icon} using the resource ID of a Bitmap image.
*
* @param resourceId The resource ID of a Bitmap image.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
*/
public Icon fromResource(@DrawableRes int resourceId) {
Drawable drawable = ContextCompat.getDrawable(mContext, resourceId);
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmap = bitmapDrawable.getBitmap();
} else {
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
}
mOptions = new BitmapFactory.Options();
mOptions.inScaled = true;
mOptions.inDensity = DisplayMetrics.DENSITY_DEFAULT;
mOptions.inTargetDensity = metrics.densityDpi;
if (realMetrics != null) {
mOptions.inScreenDensity = realMetrics.densityDpi;
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
return fromBitmap(bitmap);
}
/**
* Creates an {@link Icon} from a given Bitmap image.
*
* @param bitmap image used for creating the Icon.
* @return The {@link Icon} using the given Bitmap image.
*/
public Icon fromBitmap(@NonNull Bitmap bitmap) {
if (mNextId < 0) {
throw new TooManyIconsException();
}
String id = ICON_ID_PREFIX + ++mNextId;
return new Icon(id, bitmap);
/**
* Provides an {@link Icon} using the default marker icon used for {@link Marker}.
*
* @return An {@link Icon} with the default {@link Marker} icon.
*/
public Icon defaultMarker() {
if (mDefaultMarker == null) {
mDefaultMarker = fromResource(R.drawable.mapbox_marker_icon_default);
}
return mDefaultMarker;
}
/**
* Create an {@link Icon} from a given {@link Drawable}.
*
* @param drawable A {@link Drawable} object used for creating the {@link Icon}.
* @return {@link Icon} with the provided {@link Drawable}.
*/
public Icon fromDrawable(@NonNull Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
return fromDrawable(drawable, width, height);
/**
* Provides an {@link Icon} using the default marker icon used for {@link MarkerView}.
*
* @return An {@link Icon} with the default {@link MarkerView} icon.
*/
public Icon defaultMarkerView() {
if (mDefaultMarkerView == null) {
mDefaultMarkerView = fromResource(R.drawable.mapbox_markerview_icon_default);
}
return mDefaultMarkerView;
}
/**
* Create an {@link Icon} from a given {@link Drawable}.
*
* @param drawable A {@link Drawable} object used for creating the {@link Icon}.
* @param width An integer greater then zero defining the {@link Icon} width.
* @param height An integer greater then zero defining the {@link Icon} height.
* @return {@link Icon} with the provided {@link Drawable}.
*/
public Icon fromDrawable(@NonNull Drawable drawable, int width, int height) {
if ((width < 0) || (height < 0)) {
return null;
}
private Icon fromInputStream(@NonNull InputStream is) {
Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions);
return fromBitmap(bitmap);
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Rect temp = drawable.getBounds();
Rect bounds = new Rect(0, 0, width, height);
drawable.setBounds(bounds);
drawable.draw(canvas);
drawable.setBounds(temp);
return fromBitmap(bitmap);
/**
* Creates an {@link Icon} using the name of a Bitmap image in the assets directory.
*
* @param assetName The name of a Bitmap image in the assets directory.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
*/
public Icon fromAsset(@NonNull String assetName) {
InputStream is;
try {
is = mContext.getAssets().open(assetName);
} catch (IOException ioException) {
return null;
}
return fromInputStream(is);
}
/**
* Create an {@link Icon} using the resource ID of a Bitmap image.
*
* @param resourceId The resource ID of a Bitmap image.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
*/
public Icon fromResource(@DrawableRes int resourceId) {
Drawable drawable = ContextCompat.getDrawable(mContext, resourceId);
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmap = bitmapDrawable.getBitmap();
} else {
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
/**
* Creates an {@link Icon} using the absolute file path of a Bitmap image.
*
* @param absolutePath The absolute path of the Bitmap image.
* @return The {@link Icon} that was loaded from the absolute path or {@code null} if failed to
* load.
*/
public Icon fromPath(@NonNull String absolutePath) {
Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, mOptions);
return fromBitmap(bitmap);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
return fromBitmap(bitmap);
/**
* Create an {@link Icon} using the name of a Bitmap image file located in the internal storage.
* In particular, this calls {@link Context#openFileInput(String)}.
*
* @param fileName The name of the Bitmap image file.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
* @see <a href="https://developer.android.com/guide/topics/data/data-storage.html#filesInternal">
* Using the Internal Storage</a>
*/
public Icon fromFile(@NonNull String fileName) {
FileInputStream is;
try {
is = mContext.openFileInput(fileName);
} catch (FileNotFoundException fileNotFoundException) {
return null;
}
return fromInputStream(is);
}
/**
* Provides an {@link Icon} using the default marker icon used for {@link Marker}.
*
* @return An {@link Icon} with the default {@link Marker} icon.
*/
public Icon defaultMarker() {
if (mDefaultMarker == null) {
mDefaultMarker = fromResource(R.drawable.mapbox_marker_icon_default);
}
return mDefaultMarker;
}
/**
* Provides an {@link Icon} using the default marker icon used for {@link MarkerView}.
*
* @return An {@link Icon} with the default {@link MarkerView} icon.
*/
public Icon defaultMarkerView() {
if (mDefaultMarkerView == null) {
mDefaultMarkerView = fromResource(R.drawable.mapbox_markerview_icon_default);
}
return mDefaultMarkerView;
}
private Icon fromInputStream(@NonNull InputStream is) {
Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions);
return fromBitmap(bitmap);
}
/**
* Creates an {@link Icon} using the name of a Bitmap image in the assets directory.
*
* @param assetName The name of a Bitmap image in the assets directory.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
*/
public Icon fromAsset(@NonNull String assetName) {
InputStream is;
try {
is = mContext.getAssets().open(assetName);
} catch (IOException e) {
return null;
}
return fromInputStream(is);
}
/**
* Creates an {@link Icon} using the absolute file path of a Bitmap image.
*
* @param absolutePath The absolute path of the Bitmap image.
* @return The {@link Icon} that was loaded from the absolute path or {@code null} if failed to
* load.
*/
public Icon fromPath(@NonNull String absolutePath) {
Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, mOptions);
return fromBitmap(bitmap);
}
/**
* Create an {@link Icon} using the name of a Bitmap image file located in the internal storage.
* In particular, this calls {@link Context#openFileInput(String)}.
*
* @param fileName The name of the Bitmap image file.
* @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
* @see <a href="https://developer.android.com/guide/topics/data/data-storage.html#filesInternal">Using the Internal Storage</a>
*/
public Icon fromFile(@NonNull String fileName) {
FileInputStream is;
try {
is = mContext.openFileInput(fileName);
} catch (FileNotFoundException e) {
return null;
}
return fromInputStream(is);
}
/**
* Create an {@link Icon} using a previously created icon identifier along with a provided
* Bitmap.
*
* @param iconId The {@link Icon} identifier you'd like to recreate.
* @param bitmap a Bitmap used to replace the current one.
* @return The {@link Icon} using the new Bitmap.
*/
public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
return new Icon(iconId, bitmap);
}
/**
* Create an {@link Icon} using a previously created icon identifier along with a provided
* Bitmap.
*
* @param iconId The {@link Icon} identifier you'd like to recreate.
* @param bitmap a Bitmap used to replace the current one.
* @return The {@link Icon} using the new Bitmap.
*/
public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
return new Icon(iconId, bitmap);
}
}

View File

@@ -31,270 +31,271 @@ import java.lang.ref.WeakReference;
*/
public class InfoWindow {
private WeakReference<Marker> mBoundMarker;
private WeakReference<MapboxMap> mMapboxMap;
protected WeakReference<View> mView;
private WeakReference<Marker> boundMarker;
private WeakReference<MapboxMap> mapboxMap;
protected WeakReference<View> view;
private float mMarkerHeightOffset;
private float mMarkerWidthOffset;
private float mViewWidthOffset;
private PointF mCoordinates;
private boolean mIsVisible;
private float markerHeightOffset;
private float markerWidthOffset;
private float viewWidthOffset;
private PointF coordinates;
private boolean isVisible;
@LayoutRes
private int mLayoutRes;
@LayoutRes
private int layoutRes;
InfoWindow(MapView mapView, int layoutResId, MapboxMap mapboxMap) {
mLayoutRes = layoutResId;
View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
initialize(view, mapboxMap);
}
InfoWindow(MapView mapView, int layoutResId, MapboxMap mapboxMap) {
layoutRes = layoutResId;
View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
initialize(view, mapboxMap);
}
InfoWindow(View view, MapboxMap mapboxMap) {
initialize(view, mapboxMap);
}
InfoWindow(View view, MapboxMap mapboxMap) {
initialize(view, mapboxMap);
}
private void initialize(View view, MapboxMap mapboxMap) {
mMapboxMap = new WeakReference<>(mapboxMap);
mIsVisible = false;
mView = new WeakReference<>(view);
private void initialize(View view, MapboxMap mapboxMap) {
this.mapboxMap = new WeakReference<>(mapboxMap);
isVisible = false;
this.view = new WeakReference<>(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MapboxMap mapboxMap = mMapboxMap.get();
if (mapboxMap != null) {
MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener = mapboxMap.getOnInfoWindowClickListener();
boolean handledDefaultClick = false;
if (onInfoWindowClickListener != null) {
handledDefaultClick = onInfoWindowClickListener.onInfoWindowClick(getBoundMarker());
}
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MapboxMap mapboxMap = InfoWindow.this.mapboxMap.get();
if (mapboxMap != null) {
MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener = mapboxMap.getOnInfoWindowClickListener();
boolean handledDefaultClick = false;
if (onInfoWindowClickListener != null) {
handledDefaultClick = onInfoWindowClickListener.onInfoWindowClick(getBoundMarker());
}
if (!handledDefaultClick) {
// default behavior: close it when clicking on the tooltip:
close();
}
}
}
});
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
MapboxMap mapboxMap = mMapboxMap.get();
if (mapboxMap != null) {
MapboxMap.OnInfoWindowLongClickListener listener = mapboxMap.getOnInfoWindowLongClickListener();
if (listener != null) {
listener.onInfoWindowLongClick(getBoundMarker());
}
}
return true;
}
});
}
/**
* Open the info window at the specified position.
*
* @param boundMarker The marker on which is hooked the view.
* @param position to place the window on the map.
* @param offsetX The offset of the view to the position, in pixels. This allows to offset
* the view from the object position.
* @param offsetY The offset of the view to the position, in pixels. This allows to offset
* the view from the object position.
* @return this {@link InfoWindow}.
*/
InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) {
setBoundMarker(boundMarker);
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT);
MapboxMap mapboxMap = mMapboxMap.get();
View view = mView.get();
if (view != null && mapboxMap != null) {
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// Calculate y-offset for update method
mMarkerHeightOffset = -view.getMeasuredHeight() + offsetY;
mMarkerWidthOffset = -offsetX;
// Calculate default Android x,y coordinate
mCoordinates = mapboxMap.getProjection().toScreenLocation(position);
float x = mCoordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
float y = mCoordinates.y - view.getMeasuredHeight() + offsetY;
if (view instanceof InfoWindowView) {
// only apply repositioning/margin for InfoWindowView
Resources resources = mapView.getContext().getResources();
// get right/left popup window
float rightSideInfowWindow = x + view.getMeasuredWidth();
float leftSideInfoWindow = x;
// get right/left map view
final float mapRight = mapView.getRight();
final float mapLeft = mapView.getLeft();
float marginHorizontal = resources.getDimension(R.dimen.mapbox_infowindow_margin);
float tipViewOffset = resources.getDimension(R.dimen.mapbox_infowindow_tipview_width) / 2;
float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset;
boolean outOfBoundsLeft = false;
boolean outOfBoundsRight = false;
// only optimise margins if view is inside current viewport
if (mCoordinates.x >= 0 && mCoordinates.x <= mapView.getWidth()
&& mCoordinates.y >= 0 && mCoordinates.y <= mapView.getHeight()) {
// if out of bounds right
if (rightSideInfowWindow > mapRight) {
outOfBoundsRight = true;
x -= rightSideInfowWindow - mapRight;
tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
rightSideInfowWindow = x + view.getMeasuredWidth();
}
// fit screen left
if (leftSideInfoWindow < mapLeft) {
outOfBoundsLeft = true;
x += mapLeft - leftSideInfoWindow;
tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
leftSideInfoWindow = x;
}
// Add margin right
if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
x -= marginHorizontal - (mapRight - rightSideInfowWindow);
tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
leftSideInfoWindow = x;
}
// Add margin left
if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
x += marginHorizontal - (leftSideInfoWindow - mapLeft);
tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
}
}
// Adjust tipView
InfoWindowView infoWindowView = (InfoWindowView) view;
infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
}
// set anchor popupwindowview
view.setX(x);
view.setY(y);
// Calculate x-offset for update method
mViewWidthOffset = x - mCoordinates.x - offsetX;
close(); //if it was already opened
mapView.addView(view, lp);
mIsVisible = true;
if (!handledDefaultClick) {
// default behavior: close it when clicking on the tooltip:
close();
}
}
return this;
}
}
});
/**
* Close this {@link InfoWindow} if it is visible, otherwise calling this will do nothing.
*
* @return This {@link InfoWindow}
*/
InfoWindow close() {
MapboxMap mapboxMap = mMapboxMap.get();
if (mIsVisible && mapboxMap != null) {
mIsVisible = false;
View view = mView.get();
if (view != null && view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
Marker marker = getBoundMarker();
MapboxMap.OnInfoWindowCloseListener listener = mapboxMap.getOnInfoWindowCloseListener();
if (listener != null) {
listener.onInfoWindowClose(marker);
}
setBoundMarker(null);
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
MapboxMap mapboxMap = InfoWindow.this.mapboxMap.get();
if (mapboxMap != null) {
MapboxMap.OnInfoWindowLongClickListener listener = mapboxMap.getOnInfoWindowLongClickListener();
if (listener != null) {
listener.onInfoWindowLongClick(getBoundMarker());
}
}
return this;
}
return true;
}
});
}
/**
* Constructs the view that is displayed when the InfoWindow opens. This retrieves data from
* overlayItem and shows it in the tooltip.
*
* @param overlayItem the tapped overlay item
*/
void adaptDefaultMarker(Marker overlayItem, MapboxMap mapboxMap, MapView mapView) {
View view = mView.get();
if (view == null) {
view = LayoutInflater.from(mapView.getContext()).inflate(mLayoutRes, mapView, false);
initialize(view, mapboxMap);
}
mMapboxMap = new WeakReference<>(mapboxMap);
String title = overlayItem.getTitle();
TextView titleTextView = ((TextView) view.findViewById(R.id.infowindow_title));
if (!TextUtils.isEmpty(title)) {
titleTextView.setText(title);
titleTextView.setVisibility(View.VISIBLE);
} else {
titleTextView.setVisibility(View.GONE);
/**
* Open the info window at the specified position.
*
* @param boundMarker The marker on which is hooked the view.
* @param position to place the window on the map.
* @param offsetX The offset of the view to the position, in pixels. This allows to offset
* the view from the object position.
* @param offsetY The offset of the view to the position, in pixels. This allows to offset
* the view from the object position.
* @return this {@link InfoWindow}.
*/
InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) {
setBoundMarker(boundMarker);
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
MapView.LayoutParams.WRAP_CONTENT);
MapboxMap mapboxMap = this.mapboxMap.get();
View view = this.view.get();
if (view != null && mapboxMap != null) {
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// Calculate y-offset for update method
markerHeightOffset = -view.getMeasuredHeight() + offsetY;
markerWidthOffset = -offsetX;
// Calculate default Android x,y coordinate
coordinates = mapboxMap.getProjection().toScreenLocation(position);
float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
float y = coordinates.y - view.getMeasuredHeight() + offsetY;
if (view instanceof InfoWindowView) {
// only apply repositioning/margin for InfoWindowView
Resources resources = mapView.getContext().getResources();
// get right/left popup window
float rightSideInfowWindow = x + view.getMeasuredWidth();
float leftSideInfoWindow = x;
// get right/left map view
final float mapRight = mapView.getRight();
final float mapLeft = mapView.getLeft();
float marginHorizontal = resources.getDimension(R.dimen.mapbox_infowindow_margin);
float tipViewOffset = resources.getDimension(R.dimen.mapbox_infowindow_tipview_width) / 2;
float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset;
boolean outOfBoundsLeft = false;
boolean outOfBoundsRight = false;
// only optimise margins if view is inside current viewport
if (coordinates.x >= 0 && coordinates.x <= mapView.getWidth()
&& coordinates.y >= 0 && coordinates.y <= mapView.getHeight()) {
// if out of bounds right
if (rightSideInfowWindow > mapRight) {
outOfBoundsRight = true;
x -= rightSideInfowWindow - mapRight;
tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
rightSideInfowWindow = x + view.getMeasuredWidth();
}
// fit screen left
if (leftSideInfoWindow < mapLeft) {
outOfBoundsLeft = true;
x += mapLeft - leftSideInfoWindow;
tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
leftSideInfoWindow = x;
}
// Add margin right
if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
x -= marginHorizontal - (mapRight - rightSideInfowWindow);
tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
leftSideInfoWindow = x;
}
// Add margin left
if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
x += marginHorizontal - (leftSideInfoWindow - mapLeft);
tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
}
}
String snippet = overlayItem.getSnippet();
TextView snippetTextView = ((TextView) view.findViewById(R.id.infowindow_description));
if (!TextUtils.isEmpty(snippet)) {
snippetTextView.setText(snippet);
snippetTextView.setVisibility(View.VISIBLE);
} else {
snippetTextView.setVisibility(View.GONE);
}
// Adjust tipView
InfoWindowView infoWindowView = (InfoWindowView) view;
infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
}
// set anchor popupwindowview
view.setX(x);
view.setY(y);
// Calculate x-offset for update method
viewWidthOffset = x - coordinates.x - offsetX;
close(); //if it was already opened
mapView.addView(view, lp);
isVisible = true;
}
return this;
}
/**
* Close this {@link InfoWindow} if it is visible, otherwise calling this will do nothing.
*
* @return This {@link InfoWindow}
*/
InfoWindow close() {
MapboxMap mapboxMap = this.mapboxMap.get();
if (isVisible && mapboxMap != null) {
isVisible = false;
View view = this.view.get();
if (view != null && view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
Marker marker = getBoundMarker();
MapboxMap.OnInfoWindowCloseListener listener = mapboxMap.getOnInfoWindowCloseListener();
if (listener != null) {
listener.onInfoWindowClose(marker);
}
setBoundMarker(null);
}
return this;
}
/**
* Constructs the view that is displayed when the InfoWindow opens. This retrieves data from
* overlayItem and shows it in the tooltip.
*
* @param overlayItem the tapped overlay item
*/
void adaptDefaultMarker(Marker overlayItem, MapboxMap mapboxMap, MapView mapView) {
View view = this.view.get();
if (view == null) {
view = LayoutInflater.from(mapView.getContext()).inflate(layoutRes, mapView, false);
initialize(view, mapboxMap);
}
this.mapboxMap = new WeakReference<>(mapboxMap);
String title = overlayItem.getTitle();
TextView titleTextView = ((TextView) view.findViewById(R.id.infowindow_title));
if (!TextUtils.isEmpty(title)) {
titleTextView.setText(title);
titleTextView.setVisibility(View.VISIBLE);
} else {
titleTextView.setVisibility(View.GONE);
}
InfoWindow setBoundMarker(Marker boundMarker) {
mBoundMarker = new WeakReference<>(boundMarker);
return this;
String snippet = overlayItem.getSnippet();
TextView snippetTextView = ((TextView) view.findViewById(R.id.infowindow_description));
if (!TextUtils.isEmpty(snippet)) {
snippetTextView.setText(snippet);
snippetTextView.setVisibility(View.VISIBLE);
} else {
snippetTextView.setVisibility(View.GONE);
}
}
Marker getBoundMarker() {
if (mBoundMarker == null) {
return null;
}
return mBoundMarker.get();
InfoWindow setBoundMarker(Marker boundMarker) {
this.boundMarker = new WeakReference<>(boundMarker);
return this;
}
Marker getBoundMarker() {
if (boundMarker == null) {
return null;
}
return boundMarker.get();
}
/**
* Will result in getting this {@link InfoWindow} and updating the view being displayed.
*/
public void update() {
MapboxMap mapboxMap = mMapboxMap.get();
Marker marker = mBoundMarker.get();
View view = mView.get();
if (mapboxMap != null && marker != null && view != null) {
mCoordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
/**
* Will result in getting this {@link InfoWindow} and updating the view being displayed.
*/
public void update() {
MapboxMap mapboxMap = this.mapboxMap.get();
Marker marker = boundMarker.get();
View view = this.view.get();
if (mapboxMap != null && marker != null && view != null) {
coordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
if (view instanceof InfoWindowView) {
view.setX(mCoordinates.x + mViewWidthOffset - mMarkerWidthOffset);
} else {
view.setX(mCoordinates.x - (view.getMeasuredWidth() / 2) - mMarkerWidthOffset);
}
view.setY(mCoordinates.y + mMarkerHeightOffset);
}
if (view instanceof InfoWindowView) {
view.setX(coordinates.x + viewWidthOffset - markerWidthOffset);
} else {
view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset);
}
view.setY(coordinates.y + markerHeightOffset);
}
}
/**
* Retrieve this {@link InfoWindow}'s current view being used.
*
* @return This {@link InfoWindow}'s current View.
*/
public View getView() {
return mView != null ? mView.get() : null;
}
/**
* Retrieve this {@link InfoWindow}'s current view being used.
*
* @return This {@link InfoWindow}'s current View.
*/
public View getView() {
return view != null ? view.get() : null;
}
boolean isVisible() {
return mIsVisible;
}
boolean isVisible() {
return isVisible;
}
}

View File

@@ -12,51 +12,51 @@ import com.mapbox.mapboxsdk.R;
final class InfoWindowTipView extends View {
private Paint mPaint;
private Path mPath;
private int mLineWidth;
private Paint mPaint;
private Path mPath;
private int mLineWidth;
public InfoWindowTipView(Context context, AttributeSet attrs) {
super(context, attrs);
public InfoWindowTipView(Context context, AttributeSet attrs) {
super(context, attrs);
mPath = new Path();
mLineWidth = (int) context.getResources().getDimension(R.dimen.mapbox_infowindow_line_width);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(0.0f);
mPaint.setStyle(Paint.Style.FILL);
}
mPath = new Path();
mLineWidth = (int) context.getResources().getDimension(R.dimen.mapbox_infowindow_line_width);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(0.0f);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getMeasuredHeight();
int width = getMeasuredWidth();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getMeasuredHeight();
int width = getMeasuredWidth();
mPath.rewind();
mPath.rewind();
this.mPaint.setColor(Color.WHITE);
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(0.0f);
this.mPaint.setStyle(Paint.Style.FILL);
this.mPaint.setColor(Color.WHITE);
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(0.0f);
this.mPaint.setStyle(Paint.Style.FILL);
mPath.moveTo(0, 0);
mPath.lineTo(width, 0);
mPath.lineTo((width / 2), height);
mPath.lineTo(0, 0);
canvas.drawPath(mPath, this.mPaint);
mPath.moveTo(0, 0);
mPath.lineTo(width, 0);
mPath.lineTo((width / 2), height);
mPath.lineTo(0, 0);
canvas.drawPath(mPath, this.mPaint);
mPath.rewind();
mPath.rewind();
this.mPaint.setColor(Color.parseColor("#C2C2C2"));
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(mLineWidth);
this.mPaint.setStyle(Paint.Style.STROKE);
this.mPaint.setColor(Color.parseColor("#C2C2C2"));
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(mLineWidth);
this.mPaint.setStyle(Paint.Style.STROKE);
mPath.moveTo(0, 0);
mPath.lineTo(width / 2, height);
mPath.lineTo(width, 0);
canvas.drawPath(mPath, this.mPaint);
}
mPath.moveTo(0, 0);
mPath.lineTo(width / 2, height);
mPath.lineTo(width, 0);
canvas.drawPath(mPath, this.mPaint);
}
}

View File

@@ -9,30 +9,30 @@ import com.mapbox.mapboxsdk.R;
class InfoWindowView extends RelativeLayout {
private InfoWindowTipView mTipView;
private InfoWindowTipView mTipView;
public InfoWindowView(Context context) {
this(context, null);
}
public InfoWindowView(Context context) {
this(context, null);
}
public InfoWindowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InfoWindowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context) {
LayoutInflater.from(context).inflate(R.layout.mapbox_infowindow_content, this);
mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
}
private void initialize(Context context) {
LayoutInflater.from(context).inflate(R.layout.mapbox_infowindow_content, this);
mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
}
void setTipViewMarginLeft(int marginLeft) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
layoutParams.leftMargin = marginLeft;
// This is a bit of a hack but prevents an occasional gap between the InfoWindow
layoutParams.topMargin = (int) getResources().getDimension(R.dimen.mapbox_infowindow_offset);
}
void setTipViewMarginLeft(int marginLeft) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
layoutParams.leftMargin = marginLeft;
// This is a bit of a hack but prevents an occasional gap between the InfoWindow
layoutParams.topMargin = (int) getResources().getDimension(R.dimen.mapbox_infowindow_offset);
}
}

View File

@@ -27,249 +27,249 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public class Marker extends Annotation {
private LatLng position;
private String snippet;
private Icon icon;
private String title;
private LatLng position;
private String snippet;
private Icon icon;
private String title;
private InfoWindow infoWindow;
private boolean infoWindowShown;
private InfoWindow infoWindow;
private boolean infoWindowShown;
private int topOffsetPixels;
private int rightOffsetPixels;
private int topOffsetPixels;
private int rightOffsetPixels;
/**
* Constructor
*/
Marker() {
super();
/**
* Constructor
*/
Marker() {
super();
}
/**
* Creates a instance of {@link Marker} using the builder of Marker.
*
* @param baseMarkerOptions The builder used to construct the Marker.
*/
public Marker(BaseMarkerOptions baseMarkerOptions) {
position = baseMarkerOptions.position;
snippet = baseMarkerOptions.snippet;
icon = baseMarkerOptions.icon;
title = baseMarkerOptions.title;
}
Marker(BaseMarkerViewOptions baseMarkerViewOptions) {
position = baseMarkerViewOptions.position;
snippet = baseMarkerViewOptions.snippet;
icon = baseMarkerViewOptions.icon;
title = baseMarkerViewOptions.title;
}
Marker(LatLng position, Icon icon, String title, String snippet) {
this.position = position;
this.icon = icon;
this.title = title;
this.snippet = snippet;
}
/**
* Returns the position of the marker.
*
* @return A {@link LatLng} object specifying the marker's current position.
*/
public LatLng getPosition() {
return position;
}
/**
* Gets the snippet of the marker.
*
* @return A string containing the marker's snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Gets the snippet of the marker.
*
* @return A string containing the marker's snippet.
*/
public String getTitle() {
return title;
}
/**
* Do not use this method, used internally by the SDK.
*/
public void hideInfoWindow() {
if (infoWindow != null) {
infoWindow.close();
}
infoWindowShown = false;
}
/**
* Creates a instance of {@link Marker} using the builder of Marker.
*
* @param baseMarkerOptions The builder used to construct the Marker.
*/
public Marker(BaseMarkerOptions baseMarkerOptions) {
position = baseMarkerOptions.position;
snippet = baseMarkerOptions.snippet;
icon = baseMarkerOptions.icon;
title = baseMarkerOptions.title;
/**
* Do not use this method, used internally by the SDK.
*
* @return true if the infoWindow is shown
*/
public boolean isInfoWindowShown() {
return infoWindowShown;
}
/**
* Sets the location of the marker.
*
* @param position A {@link LatLng} defining the marker position.
*/
public void setPosition(LatLng position) {
this.position = position;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
Marker(BaseMarkerViewOptions baseMarkerViewOptions) {
position = baseMarkerViewOptions.position;
snippet = baseMarkerViewOptions.snippet;
icon = baseMarkerViewOptions.icon;
title = baseMarkerViewOptions.title;
/**
* Sets the snippet of the marker.
*
* @param snippet A String used in the marker info window. If {@code null}, the snippet is
* cleared.
*/
public void setSnippet(String snippet) {
this.snippet = snippet;
refreshInfoWindowContent();
}
/**
* Sets the icon of the marker.
*
* @param icon The {@link Icon} to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
Marker(LatLng position, Icon icon, String title, String snippet) {
this.position = position;
this.icon = icon;
this.title = title;
this.snippet = snippet;
/**
* Gets the {@link Icon} currently used for the marker. If no Icon was set for the marker, the
* default icon will be returned.
*
* @return The {@link Icon} the marker is using.
*/
public Icon getIcon() {
return icon;
}
/**
* Sets the title of the marker.
*
* @param title A String used in the marker info window. If {@code null}, the title is
* cleared.
*/
public void setTitle(String title) {
this.title = title;
refreshInfoWindowContent();
}
/**
* Gets the {@link InfoWindow} the marker is using. If the marker hasn't had an info window
* defined, this will return {@code null}.
*
* @return The info window the marker is using.
*/
@Nullable
public InfoWindow getInfoWindow() {
return infoWindow;
}
/**
* Update only for default Marker's InfoWindow content for Title and Snippet
*/
private void refreshInfoWindowContent() {
if (isInfoWindowShown() && mapView != null && mapboxMap != null && mapboxMap.getInfoWindowAdapter() == null) {
InfoWindow infoWindow = getInfoWindow(mapView);
if (mapView.getContext() != null) {
infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
}
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
infoWindow.update();
}
}
/**
* Returns the position of the marker.
*
* @return A {@link LatLng} object specifying the marker's current position.
*/
public LatLng getPosition() {
return position;
}
/**
* Gets the snippet of the marker.
*
* @return A string containing the marker's snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Gets the snippet of the marker.
*
* @return A string containing the marker's snippet.
*/
public String getTitle() {
return title;
}
/**
* Do not use this method, used internally by the SDK.
*/
public void hideInfoWindow() {
if (infoWindow != null) {
infoWindow.close();
}
infoWindowShown = false;
}
/**
* Do not use this method, used internally by the SDK.
*
* @return true if the infoWindow is shown
*/
public boolean isInfoWindowShown() {
return infoWindowShown;
}
/**
* Sets the location of the marker.
*
* @param position A {@link LatLng} defining the marker position.
*/
public void setPosition(LatLng position) {
this.position = position;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
/**
* Sets the snippet of the marker.
*
* @param snippet A String used in the marker info window. If {@code null}, the snippet is
* cleared.
*/
public void setSnippet(String snippet) {
this.snippet = snippet;
refreshInfoWindowContent();
}
/**
* Sets the icon of the marker.
*
* @param icon The {@link Icon} to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
/**
* Gets the {@link Icon} currently used for the marker. If no Icon was set for the marker, the
* default icon will be returned.
*
* @return The {@link Icon} the marker is using.
*/
public Icon getIcon() {
return icon;
}
/**
* Sets the title of the marker.
*
* @param title A String used in the marker info window. If {@code null}, the title is
* cleared.
*/
public void setTitle(String title) {
this.title = title;
refreshInfoWindowContent();
}
/**
* Gets the {@link InfoWindow} the marker is using. If the marker hasn't had an info window
* defined, this will return {@code null}.
*
* @return
*/
@Nullable
public InfoWindow getInfoWindow() {
/**
* Do not use this method, used internally by the SDK. Use {@link MapboxMap#selectMarker(Marker)}
* if you want to programmatically display the markers info window.
*
* @param mapboxMap The hosting mapbox map.
* @param mapView The hosting map view.
* @return The info window that was shown.
*/
public InfoWindow showInfoWindow(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
setMapboxMap(mapboxMap);
setMapView(mapView);
MapboxMap.InfoWindowAdapter infoWindowAdapter = getMapboxMap().getInfoWindowAdapter();
if (infoWindowAdapter != null) {
// end developer is using a custom InfoWindowAdapter
View content = infoWindowAdapter.getInfoWindow(this);
if (content != null) {
infoWindow = new InfoWindow(content, mapboxMap);
showInfoWindow(infoWindow, mapView);
return infoWindow;
}
}
/**
* Update only for default Marker's InfoWindow content for Title and Snippet
*/
private void refreshInfoWindowContent() {
if (isInfoWindowShown() && mapView != null && mapboxMap != null && mapboxMap.getInfoWindowAdapter() == null) {
InfoWindow infoWindow = getInfoWindow(mapView);
if (mapView.getContext() != null) {
infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
}
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
infoWindow.update();
}
InfoWindow infoWindow = getInfoWindow(mapView);
if (mapView.getContext() != null) {
infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
}
return showInfoWindow(infoWindow, mapView);
}
/**
* Do not use this method, used internally by the SDK. Use {@link MapboxMap#selectMarker(Marker)}
* if you want to programmatically display the markers info window.
*
* @param mapboxMap The hosting mapbox map.
* @param mapView The hosting map view.
* @return The info window that was shown.
*/
public InfoWindow showInfoWindow(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
setMapboxMap(mapboxMap);
setMapView(mapView);
MapboxMap.InfoWindowAdapter infoWindowAdapter = getMapboxMap().getInfoWindowAdapter();
if (infoWindowAdapter != null) {
// end developer is using a custom InfoWindowAdapter
View content = infoWindowAdapter.getInfoWindow(this);
if (content != null) {
infoWindow = new InfoWindow(content, mapboxMap);
showInfoWindow(infoWindow, mapView);
return infoWindow;
}
}
private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
iw.open(mapView, this, getPosition(), rightOffsetPixels, topOffsetPixels);
infoWindowShown = true;
return iw;
}
InfoWindow infoWindow = getInfoWindow(mapView);
if (mapView.getContext() != null) {
infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
}
return showInfoWindow(infoWindow, mapView);
private InfoWindow getInfoWindow(@NonNull MapView mapView) {
if (infoWindow == null && mapView.getContext() != null) {
infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_view, getMapboxMap());
}
return infoWindow;
}
private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
iw.open(mapView, this, getPosition(), rightOffsetPixels, topOffsetPixels);
infoWindowShown = true;
return iw;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param topOffsetPixels the top offset pixels.
*/
public void setTopOffsetPixels(int topOffsetPixels) {
this.topOffsetPixels = topOffsetPixels;
}
private InfoWindow getInfoWindow(@NonNull MapView mapView) {
if (infoWindow == null && mapView.getContext() != null) {
infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_view, getMapboxMap());
}
return infoWindow;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param rightOffsetPixels the right offset pixels.
*/
public void setRightOffsetPixels(int rightOffsetPixels) {
this.rightOffsetPixels = rightOffsetPixels;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param topOffsetPixels the top offset pixels.
*/
public void setTopOffsetPixels(int topOffsetPixels) {
this.topOffsetPixels = topOffsetPixels;
}
/**
* Do not use this method, used internally by the SDK.
*
* @param rightOffsetPixels the right offset pixels.
*/
public void setRightOffsetPixels(int rightOffsetPixels) {
this.rightOffsetPixels = rightOffsetPixels;
}
/**
* Returns a String with the marker position.
*
* @return A String with the marker position.
*/
@Override
public String toString() {
return "Marker [position[" + getPosition() + "]]";
}
/**
* Returns a String with the marker position.
*
* @return A String with the marker position.
*/
@Override
public String toString() {
return "Marker [position[" + getPosition() + "]]";
}
}

View File

@@ -21,161 +21,168 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
*/
public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions> implements Parcelable {
/**
* Defines options for a Marker.
*/
public MarkerOptions() {
/**
* Defines options for a Marker.
*/
public MarkerOptions() {
}
protected MarkerOptions(Parcel in) {
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
title(in.readString());
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
Icon icon = new Icon(iconId, iconBitmap);
icon(icon);
}
}
@Override
public MarkerOptions getThis() {
return this;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(getPosition(), flags);
out.writeString(getSnippet());
out.writeString(getTitle());
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
out.writeString(getIcon().getId());
out.writeParcelable(getIcon().getBitmap(), flags);
}
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return Marker The build marker
*/
public Marker getMarker() {
if (position == null) {
throw new InvalidMarkerPositionException();
}
protected MarkerOptions(Parcel in) {
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
title(in.readString());
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
Icon icon = new Icon(iconId, iconBitmap);
icon(icon);
}
}
return new Marker(position, icon, title, snippet);
}
@Override
public MarkerOptions getThis() {
return this;
}
/**
* Returns the position set for this {@link MarkerOptions} object.
*
* @return A {@link LatLng} object specifying the marker's current position.
*/
public LatLng getPosition() {
return position;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Gets the snippet set for this {@link MarkerOptions} object.
*
* @return A string containing the marker's snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(getPosition(), flags);
out.writeString(getSnippet());
out.writeString(getTitle());
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
out.writeString(getIcon().getId());
out.writeParcelable(getIcon().getBitmap(), flags);
}
}
/**
* Gets the title set for this {@link MarkerOptions} object.
*
* @return A string containing the marker's title.
*/
public String getTitle() {
return title;
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return Marker The build marker
*/
public Marker getMarker() {
if (position == null) {
throw new InvalidMarkerPositionException();
}
/**
* Gets the custom icon set for this {@link MarkerOptions} object.
*
* @return A {@link Icon} object that the marker is using. If the icon wasn't set, default icon
* will return.
*/
public Icon getIcon() {
return icon;
}
return new Marker(position, icon, title, snippet);
}
public static final Parcelable.Creator<MarkerOptions> CREATOR =
new Parcelable.Creator<MarkerOptions>() {
public MarkerOptions createFromParcel(Parcel in) {
return new MarkerOptions(in);
}
/**
* Returns the position set for this {@link MarkerOptions} object.
*
* @return A {@link LatLng} object specifying the marker's current position.
*/
public LatLng getPosition() {
return position;
}
/**
* Gets the snippet set for this {@link MarkerOptions} object.
*
* @return A string containing the marker's snippet.
*/
public String getSnippet() {
return snippet;
}
/**
* Gets the title set for this {@link MarkerOptions} object.
*
* @return A string containing the marker's title.
*/
public String getTitle() {
return title;
}
/**
* Gets the custom icon set for this {@link MarkerOptions} object.
*
* @return A {@link Icon} object that the marker is using. If the icon wasn't set, default icon
* will return.
*/
public Icon getIcon() {
return icon;
}
public static final Parcelable.Creator<MarkerOptions> CREATOR
= new Parcelable.Creator<MarkerOptions>() {
public MarkerOptions createFromParcel(Parcel in) {
return new MarkerOptions(in);
}
public MarkerOptions[] newArray(int size) {
return new MarkerOptions[size];
}
public MarkerOptions[] newArray(int size) {
return new MarkerOptions[size];
}
};
/**
* Compares this {@link MarkerOptions} object with another {@link MarkerOptions} and
* determines if their properties match.
*
* @param o Another {@link MarkerOptions} to compare with this object.
* @return True if marker properties match this {@link MarkerOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MarkerOptions marker = (MarkerOptions) o;
if (getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null)
return false;
if (getSnippet() != null ? !getSnippet().equals(marker.getSnippet()) : marker.getSnippet() != null)
return false;
if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null)
return false;
return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null);
/**
* Compares this {@link MarkerOptions} object with another {@link MarkerOptions} and
* determines if their properties match.
*
* @param o Another {@link MarkerOptions} to compare with this object.
* @return True if marker properties match this {@link MarkerOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0);
result = 31 * result + (getSnippet() != null ? getSnippet().hashCode() : 0);
result = 31 * result + (getIcon() != null ? getIcon().hashCode() : 0);
result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0);
return result;
MarkerOptions marker = (MarkerOptions) o;
if (getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null) {
return false;
}
if (getSnippet() != null ? !getSnippet().equals(marker.getSnippet()) : marker.getSnippet() != null) {
return false;
}
if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null) {
return false;
}
return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null);
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0);
result = 31 * result + (getSnippet() != null ? getSnippet().hashCode() : 0);
result = 31 * result + (getIcon() != null ? getIcon().hashCode() : 0);
result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0);
return result;
}
}

View File

@@ -26,382 +26,384 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public class MarkerView extends Marker {
private MarkerViewManager markerViewManager;
private MarkerViewManager markerViewManager;
private float width;
private float height;
private float width;
private float height;
private float anchorU;
private float anchorV;
private float anchorU;
private float anchorV;
private float offsetX = MapboxConstants.UNMEASURED;
private float offsetY = MapboxConstants.UNMEASURED;
private float offsetX = MapboxConstants.UNMEASURED;
private float offsetY = MapboxConstants.UNMEASURED;
private float infoWindowAnchorU;
private float infoWindowAnchorV;
private float infoWindowAnchorU;
private float infoWindowAnchorV;
private boolean flat;
private boolean visible = true;
private boolean flat;
private boolean visible = true;
private float tiltValue;
private float rotation;
private float alpha = 1;
private float tiltValue;
private float rotation;
private float alpha = 1;
private Icon markerViewIcon;
private Icon markerViewIcon;
private boolean selected;
private boolean selected;
/**
* Publicly hidden default constructor
*/
MarkerView() {
/**
* Publicly hidden default constructor
*/
MarkerView() {
}
/**
* Creates a instance of MarkerView using the builder of MarkerView
*
* @param baseMarkerViewOptions the builder used to construct the MarkerView
*/
public MarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
super(baseMarkerViewOptions);
this.alpha = baseMarkerViewOptions.getAlpha();
this.anchorU = baseMarkerViewOptions.getAnchorU();
this.anchorV = baseMarkerViewOptions.getAnchorV();
this.infoWindowAnchorU = baseMarkerViewOptions.getInfoWindowAnchorU();
this.infoWindowAnchorV = baseMarkerViewOptions.getInfoWindowAnchorV();
this.flat = baseMarkerViewOptions.isFlat();
this.rotation = baseMarkerViewOptions.getRotation();
this.selected = baseMarkerViewOptions.selected;
}
float getWidth() {
return width;
}
void setWidth(float width) {
this.width = width;
}
float getHeight() {
return height;
}
void setHeight(float height) {
this.height = height;
}
/**
* Specifies the anchor being set on a particular point of the MarkerView.
* <p>
* The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
* is the top-left corner of the image, and (1, 1) is the bottom-right corner.
* </p>
*
* @param u u-coordinate of the anchor, as a ratio of the image width (in the range [0, 1]).
* @param v v-coordinate of the anchor, as a ratio of the image height (in the range [0, 1]).
*/
public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
setOffset(-1, -1);
}
/**
* Get the horizontal distance, normalized to [0, 1], of the anchor from the left edge.
*
* @return The u-value of the anchor.
*/
public float getAnchorU() {
return anchorU;
}
/**
* Get the vertical distance, normalized to [0, 1], of the anchor from the top edge.
*
* @return the v-value of the anchor.
*/
public float getAnchorV() {
return anchorV;
}
/**
* Internal method to set the calculated offset.
* <p>
* These are calculated based on the View bounds and the provided anchor.
* </p>
*
* @param x the x-value of the offset.
* @param y the y-value of the offset.
*/
void setOffset(float x, float y) {
offsetX = x;
offsetY = y;
}
/**
* Internal method to get the horizontal calculated offset.
*
* @return the calculated horizontal offset.
*/
float getOffsetX() {
return offsetX;
}
/**
* Internal method to get the vertical calculated offset.
*
* @return the calculated vertical offset.
*/
float getOffsetY() {
return offsetY;
}
/**
* Specifies the anchor point of the info window on the View of the MarkerView.
* <p>
* The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
* is the top-left corner of the image, and (1, 1) is the bottom-right corner.
* </p>
* <p>
* The default is the top middle of the View.
* </p>
*
* @param u u-coordinate of the info window anchor, as a ratio of the image width (in the range [0, 1]).
* @param v v-coordinate of the info window anchor, as a ratio of the image height (in the range [0, 1]).
* @see #setAnchor(float, float) for more details.
*/
public void setInfoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u,
@FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
}
/**
* Get the horizontal distance, normalized to [0, 1], of the info window anchor from the left edge.
*
* @return the u value of the InfoWindow anchor.
*/
public float getInfoWindowAnchorU() {
return infoWindowAnchorU;
}
/**
* Get the vertical distance, normalized to [0, 1], of the info window anchor from the top edge.
*
* @return the v value of the InfoWindow anchor.
*/
public float getInfoWindowAnchorV() {
return infoWindowAnchorV;
}
/**
* Get the flat state of a MarkerView.
*
* @return true if the MarkerView is flat; false if the MarkerView is billboard.
*/
public boolean isFlat() {
return flat;
}
/**
* Sets whether this MarkerView should be flat against the map (true) or a billboard facing the
* camera (false).
*
* @param flat the flat state of the MarkerView.
*/
public void setFlat(boolean flat) {
this.flat = flat;
}
/**
* Internal method to get the current tilted value of a MarkerView.
*
* @return the tilted value.
*/
float getTilt() {
return tiltValue;
}
/**
* Internal method to set the current titled value of a MarkerView.
*
* @param tiltValue the tilted value to set.
*/
void setTilt(@FloatRange(from = 0.0, to = MapboxConstants.MAXIMUM_TILT) float tiltValue) {
this.tiltValue = tiltValue;
}
/**
* Set the visible state of a MarkerView.
*
* @param visible true will make the MarkerView visible, false will hide the MarkerView.
*/
public void setVisible(boolean visible) {
this.visible = visible;
if (markerViewManager != null) {
markerViewManager.animateVisible(this, visible);
}
}
/**
* Returns the visible state of the MarkerView.
*
* @return the visible state.
*/
public boolean isVisible() {
return visible;
}
/**
* Set the rotation value of the MarkerView in degrees.
* <p>
* Input will be limited to 0 - 360 degrees.
* </p>
* <p>
* This will result in animating the rotation of the MarkerView using an rotation animator
* from current value to the provided parameter value.
* </p>
*
* @param rotation the rotation value to animate to.
*/
public void setRotation(float rotation) {
// limit to 0 - 360 degrees
float newRotation = rotation;
while (newRotation > 360) {
newRotation -= 360;
}
while (newRotation < 0) {
newRotation += 360;
}
/**
* Creates a instance of MarkerView using the builder of MarkerView
*
* @param baseMarkerViewOptions the builder used to construct the MarkerView
*/
public MarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
super(baseMarkerViewOptions);
this.alpha = baseMarkerViewOptions.getAlpha();
this.anchorU = baseMarkerViewOptions.getAnchorU();
this.anchorV = baseMarkerViewOptions.getAnchorV();
this.infoWindowAnchorU = baseMarkerViewOptions.getInfoWindowAnchorU();
this.infoWindowAnchorV = baseMarkerViewOptions.getInfoWindowAnchorV();
this.flat = baseMarkerViewOptions.isFlat();
this.rotation = baseMarkerViewOptions.getRotation();
this.selected = baseMarkerViewOptions.selected;
this.rotation = newRotation;
if (markerViewManager != null) {
markerViewManager.animateRotationBy(this, newRotation);
}
}
float getWidth() {
return width;
/**
* Get the rotation value of the MarkerView.
*
* @return the rotation value.
*/
public float getRotation() {
return rotation;
}
/**
* Get the alpha value of the MarkerView.
*
* @return the alpha value.
*/
public float getAlpha() {
return alpha;
}
/**
* Set the alpha value of the MarkerView.
* <p>
* This will result in animating the alpha of the MarkerView using an alpha animator
* from current value to the provided parameter value.
* </p>
*
* @param alpha the alpha value to animate to.
*/
public void setAlpha(@FloatRange(from = 0.0, to = 255.0) float alpha) {
this.alpha = alpha;
if (markerViewManager != null) {
markerViewManager.animateAlpha(this, alpha);
}
}
void setWidth(float width) {
this.width = width;
/**
* Set the icon of the MarkerView.
*
* @param icon the {@link Icon} to be used as Marker image.
*/
@Override
public void setIcon(@Nullable Icon icon) {
if (icon != null) {
markerViewIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, icon.getBitmap());
}
float getHeight() {
return height;
Icon transparentIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID,
IconFactory.ICON_MARKERVIEW_BITMAP);
if (markerViewManager != null) {
markerViewManager.updateIcon(this);
}
super.setIcon(transparentIcon);
}
void setHeight(float height) {
this.height = height;
/**
* Sets the location of the marker.
*
* @param position A {@link LatLng} defining the marker position.
*/
@Override
public void setPosition(LatLng position) {
super.setPosition(position);
if (markerViewManager != null) {
markerViewManager.update();
}
}
/**
* Specifies the anchor being set on a particular point of the MarkerView.
* <p>
* The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
* is the top-left corner of the image, and (1, 1) is the bottom-right corner.
* </p>
*
* @param u u-coordinate of the anchor, as a ratio of the image width (in the range [0, 1]).
* @param v v-coordinate of the anchor, as a ratio of the image height (in the range [0, 1]).
*/
public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
setOffset(-1, -1);
/**
* Determine if the {@link MarkerView} is selected or not.
*
* @return True if the MarkerView's selected, else false.
*/
public boolean isSelected() {
return selected;
}
/**
* For internal use only, use {@link MapboxMap#selectMarker(Marker)} instead.
*/
void setSelected(boolean selected) {
this.selected = selected;
}
/**
* Get the icon of the MarkerView.
*
* @return the icon use as Marker image.
*/
@Override
public Icon getIcon() {
return markerViewIcon;
}
/**
* Set the MapboxMap associated tot the MapView containing the MarkerView.
* <p>
* This method is used to instantiate the MarkerView and provide an instance of
* {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}
* </p>
* <p>
* This method is used to notify that a MarkerView is no longer active by setting a null value.
* </p>
*
* @param mapboxMap the MapboxMap instances.
*/
@Override
public void setMapboxMap(MapboxMap mapboxMap) {
super.setMapboxMap(mapboxMap);
if (mapboxMap != null) {
if (isFlat()) {
// initial tilt value if MapboxMap is started with a tilt attribute
tiltValue = (float) mapboxMap.getCameraPosition().tilt;
}
markerViewManager = mapboxMap.getMarkerViewManager();
}
}
/**
* Get the horizontal distance, normalized to [0, 1], of the anchor from the left edge.
*
* @return The u-value of the anchor.
*/
public float getAnchorU() {
return anchorU;
}
/**
* Get the vertical distance, normalized to [0, 1], of the anchor from the top edge.
*
* @return the v-value of the anchor.
*/
public float getAnchorV() {
return anchorV;
}
/**
* Internal method to set the calculated offset.
* <p>
* These are calculated based on the View bounds and the provided anchor.
* </p>
*
* @param x the x-value of the offset.
* @param y the y-value of the offset.
*/
void setOffset(float x, float y) {
offsetX = x;
offsetY = y;
}
/**
* Internal method to get the horizontal calculated offset.
*
* @return the calculated horizontal offset.
*/
float getOffsetX() {
return offsetX;
}
/**
* Internal method to get the vertical calculated offset.
*
* @return the calculated vertical offset.
*/
float getOffsetY() {
return offsetY;
}
/**
* Specifies the anchor point of the info window on the View of the MarkerView.
* <p>
* The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
* is the top-left corner of the image, and (1, 1) is the bottom-right corner.
* </p>
* <p>
* The default is the top middle of the View.
* </p>
*
* @param u u-coordinate of the info window anchor, as a ratio of the image width (in the range [0, 1]).
* @param v v-coordinate of the info window anchor, as a ratio of the image height (in the range [0, 1]).
* @see #setAnchor(float, float) for more details.
*/
public void setInfoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
}
/**
* Get the horizontal distance, normalized to [0, 1], of the info window anchor from the left edge.
*
* @return the u value of the InfoWindow anchor.
*/
public float getInfoWindowAnchorU() {
return infoWindowAnchorU;
}
/**
* Get the vertical distance, normalized to [0, 1], of the info window anchor from the top edge.
*
* @return the v value of the InfoWindow anchor.
*/
public float getInfoWindowAnchorV() {
return infoWindowAnchorV;
}
/**
* Get the flat state of a MarkerView.
*
* @return true if the MarkerView is flat; false if the MarkerView is billboard.
*/
public boolean isFlat() {
return flat;
}
/**
* Sets whether this MarkerView should be flat against the map (true) or a billboard facing the
* camera (false).
*
* @param flat the flat state of the MarkerView.
*/
public void setFlat(boolean flat) {
this.flat = flat;
}
/**
* Internal method to get the current tilted value of a MarkerView.
*
* @return the tilted value.
*/
float getTilt() {
return tiltValue;
}
/**
* Internal method to set the current titled value of a MarkerView.
*
* @param tiltValue the tilted value to set.
*/
void setTilt(@FloatRange(from = 0.0, to = MapboxConstants.MAXIMUM_TILT) float tiltValue) {
this.tiltValue = tiltValue;
}
/**
* Set the visible state of a MarkerView.
*
* @param visible true will make the MarkerView visible, false will hide the MarkerView.
*/
public void setVisible(boolean visible) {
this.visible = visible;
if (markerViewManager != null) {
markerViewManager.animateVisible(this, visible);
}
}
/**
* Returns the visible state of the MarkerView.
*
* @return the visible state.
*/
public boolean isVisible() {
return visible;
}
/**
* Set the rotation value of the MarkerView in degrees.
* <p>
* Input will be limited to 0 - 360 degrees.
* </p>
* <p>
* This will result in animating the rotation of the MarkerView using an rotation animator
* from current value to the provided parameter value.
* </p>
*
* @param rotation the rotation value to animate to.
*/
public void setRotation(float rotation) {
// limit to 0 - 360 degrees
float newRotation = rotation;
while (newRotation > 360) {
newRotation -= 360;
}
while (newRotation < 0) {
newRotation += 360;
}
this.rotation = newRotation;
if (markerViewManager != null) {
markerViewManager.animateRotationBy(this, newRotation);
}
}
/**
* Get the rotation value of the MarkerView.
*
* @return the rotation value.
*/
public float getRotation() {
return rotation;
}
/**
* Get the alpha value of the MarkerView.
*
* @return the alpha value.
*/
public float getAlpha() {
return alpha;
}
/**
* Set the alpha value of the MarkerView.
* <p>
* This will result in animating the alpha of the MarkerView using an alpha animator
* from current value to the provided parameter value.
* </p>
*
* @param alpha the alpha value to animate to.
*/
public void setAlpha(@FloatRange(from = 0.0, to = 255.0) float alpha) {
this.alpha = alpha;
if (markerViewManager != null) {
markerViewManager.animateAlpha(this, alpha);
}
}
/**
* Set the icon of the MarkerView.
*
* @param icon the {@link Icon} to be used as Marker image.
*/
@Override
public void setIcon(@Nullable Icon icon) {
if (icon != null) {
markerViewIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, icon.getBitmap());
}
Icon transparentIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID,
IconFactory.ICON_MARKERVIEW_BITMAP);
if (markerViewManager != null) {
markerViewManager.updateIcon(this);
}
super.setIcon(transparentIcon);
}
/**
* Sets the location of the marker.
*
* @param position A {@link LatLng} defining the marker position.
*/
@Override
public void setPosition(LatLng position) {
super.setPosition(position);
if (markerViewManager != null) {
markerViewManager.update();
}
}
/**
* Determine if the {@link MarkerView} is selected or not.
*
* @return True if the MarkerView's selected, else false.
*/
public boolean isSelected() {
return selected;
}
/**
* For internal use only, use {@link MapboxMap#selectMarker(Marker)} instead.
*/
void setSelected(boolean selected) {
this.selected = selected;
}
/**
* Get the icon of the MarkerView.
*
* @return the icon use as Marker image.
*/
@Override
public Icon getIcon() {
return markerViewIcon;
}
/**
* Set the MapboxMap associated tot the MapView containing the MarkerView.
* <p>
* This method is used to instantiate the MarkerView and provide an instance of {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}
* </p>
* <p>
* This method is used to notify that a MarkerView is no longer active by setting a null value.
* </p>
*
* @param mapboxMap the MapboxMap instances.
*/
@Override
public void setMapboxMap(MapboxMap mapboxMap) {
super.setMapboxMap(mapboxMap);
if (mapboxMap != null) {
if (isFlat()) {
// initial tilt value if MapboxMap is started with a tilt attribute
tiltValue = (float) mapboxMap.getCameraPosition().tilt;
}
markerViewManager = mapboxMap.getMarkerViewManager();
}
}
/**
* Get the String representation of a MarkerView.
*
* @return the String representation.
*/
@Override
public String toString() {
return "MarkerView [position[" + getPosition() + "]]";
}
/**
* Get the String representation of a MarkerView.
*
* @return the String representation.
*/
@Override
public String toString() {
return "MarkerView [position[" + getPosition() + "]]";
}
}

View File

@@ -15,146 +15,150 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
*/
public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerViewOptions> {
private MarkerView marker;
private MarkerView marker;
/**
* Defines default options for a MarkerView. Extend {@link BaseMarkerViewOptions} if you need
* more customization.
*/
public MarkerViewOptions() {
marker = new MarkerView();
/**
* Defines default options for a MarkerView. Extend {@link BaseMarkerViewOptions} if you need
* more customization.
*/
public MarkerViewOptions() {
marker = new MarkerView();
}
protected MarkerViewOptions(Parcel in) {
marker = new MarkerView();
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
title(in.readString());
flat(in.readByte() != 0);
anchor(in.readFloat(), in.readFloat());
infoWindowAnchor(in.readFloat(), in.readFloat());
rotation(in.readFloat());
visible(in.readByte() != 0);
alpha(in.readFloat());
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
Icon icon = new Icon(iconId, iconBitmap);
icon(icon);
}
}
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which this method was called.
*/
@Override
public MarkerViewOptions getThis() {
return this;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(getPosition(), flags);
out.writeString(getSnippet());
out.writeString(getTitle());
out.writeByte((byte) (isFlat() ? 1 : 0));
out.writeFloat(getAnchorU());
out.writeFloat(getAnchorV());
out.writeFloat(getInfoWindowAnchorU());
out.writeFloat(getInfoWindowAnchorV());
out.writeFloat(getRotation());
out.writeByte((byte) (isVisible() ? 1 : 0));
out.writeFloat(alpha);
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
out.writeString(getIcon().getId());
out.writeParcelable(getIcon().getBitmap(), flags);
}
}
/**
* Get the {@link MarkerView}.
*
* @return {@link MarkerView}.
*/
@Override
public MarkerView getMarker() {
if (position == null) {
throw new InvalidMarkerPositionException();
}
protected MarkerViewOptions(Parcel in) {
marker = new MarkerView();
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
title(in.readString());
flat(in.readByte() != 0);
anchor(in.readFloat(), in.readFloat());
infoWindowAnchor(in.readFloat(), in.readFloat());
rotation(in.readFloat());
visible(in.readByte() != 0);
alpha(in.readFloat());
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
Icon icon = new Icon(iconId, iconBitmap);
icon(icon);
}
}
marker.setPosition(position);
marker.setSnippet(snippet);
marker.setTitle(title);
marker.setIcon(icon);
marker.setFlat(flat);
marker.setAnchor(anchorU, anchorV);
marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
marker.setRotation(rotation);
marker.setVisible(visible);
marker.setAlpha(alpha);
return marker;
}
/**
* Get the instance of the object for which this method was called.
*
* @return the object for which this method was called.
*/
@Override
public MarkerViewOptions getThis() {
return this;
}
public static final Parcelable.Creator<MarkerViewOptions> CREATOR =
new Parcelable.Creator<MarkerViewOptions>() {
public MarkerViewOptions createFromParcel(Parcel in) {
return new MarkerViewOptions(in);
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(getPosition(), flags);
out.writeString(getSnippet());
out.writeString(getTitle());
out.writeByte((byte) (isFlat() ? 1 : 0));
out.writeFloat(getAnchorU());
out.writeFloat(getAnchorV());
out.writeFloat(getInfoWindowAnchorU());
out.writeFloat(getInfoWindowAnchorV());
out.writeFloat(getRotation());
out.writeByte((byte) (isVisible() ? 1 : 0));
out.writeFloat(alpha);
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
out.writeString(getIcon().getId());
out.writeParcelable(getIcon().getBitmap(), flags);
}
}
/**
* Get the {@link MarkerView}.
*
* @return {@link MarkerView}.
*/
@Override
public MarkerView getMarker() {
if (position == null) {
throw new InvalidMarkerPositionException();
}
marker.setPosition(position);
marker.setSnippet(snippet);
marker.setTitle(title);
marker.setIcon(icon);
marker.setFlat(flat);
marker.setAnchor(anchorU, anchorV);
marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
marker.setRotation(rotation);
marker.setVisible(visible);
marker.setAlpha(alpha);
return marker;
}
public static final Parcelable.Creator<MarkerViewOptions> CREATOR
= new Parcelable.Creator<MarkerViewOptions>() {
public MarkerViewOptions createFromParcel(Parcel in) {
return new MarkerViewOptions(in);
}
public MarkerViewOptions[] newArray(int size) {
return new MarkerViewOptions[size];
}
public MarkerViewOptions[] newArray(int size) {
return new MarkerViewOptions[size];
}
};
/**
* Compares this {@link MarkerViewOptions} object with another {@link MarkerViewOptions} and
* determines if they match.
*
* @param o Another {@link MarkerViewOptions} to compare with this object.
* @return True if the {@link MarkerViewOptions} being passed in matches this
* {@link PolylineOptions} object. Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MarkerViewOptions that = (MarkerViewOptions) o;
return marker != null ? marker.equals(that.marker) : that.marker == null;
/**
* Compares this {@link MarkerViewOptions} object with another {@link MarkerViewOptions} and
* determines if they match.
*
* @param object Another {@link MarkerViewOptions} to compare with this object.
* @return True if the {@link MarkerViewOptions} being passed in matches this
* {@link PolylineOptions} object. Else, false.
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
MarkerViewOptions that = (MarkerViewOptions) object;
return marker != null ? marker.equals(that.marker) : that.marker == null;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
return marker != null ? marker.hashCode() : 0;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
return marker != null ? marker.hashCode() : 0;
}
}

View File

@@ -10,62 +10,62 @@ import java.util.List;
*/
public abstract class MultiPoint extends Annotation {
private List<LatLng> points;
private float alpha = 1.0f;
private List<LatLng> points;
private float alpha = 1.0f;
protected MultiPoint() {
super();
points = new ArrayList<>();
}
protected MultiPoint() {
super();
points = new ArrayList<>();
}
/**
* Returns a copy of the points.
*
* @return A {@link List} of points.
*/
public List<LatLng> getPoints() {
return new ArrayList<>(points);
}
/**
* Returns a copy of the points.
*
* @return A {@link List} of points.
*/
public List<LatLng> getPoints() {
return new ArrayList<>(points);
}
/**
* Sets the points of this polyline. This method will take a copy of the points, so further
* mutations to points will have no effect on this polyline.
*
* @param points A {@link List} of {@link LatLng} points making up the polyline.
*/
public void setPoints(List<LatLng> points) {
this.points = new ArrayList<>(points);
update();
}
/**
* Sets the points of this polyline. This method will take a copy of the points, so further
* mutations to points will have no effect on this polyline.
*
* @param points A {@link List} of {@link LatLng} points making up the polyline.
*/
public void setPoints(List<LatLng> points) {
this.points = new ArrayList<>(points);
update();
}
/**
* Add a point to the polyline.
*
* @param point A {@link LatLng} point to be added.
*/
public void addPoint(LatLng point) {
points.add(point);
update();
}
/**
* Add a point to the polyline.
*
* @param point A {@link LatLng} point to be added.
*/
public void addPoint(LatLng point) {
points.add(point);
update();
}
/**
* Value between 0 and 1 defining the polyline alpha.
*
* @return float value between 0 and 1.
*/
public float getAlpha() {
return alpha;
}
/**
* Value between 0 and 1 defining the polyline alpha.
*
* @return float value between 0 and 1.
*/
public float getAlpha() {
return alpha;
}
/**
* Set this {@link MultiPoint}s alpha.
*
* @param alpha float value between 0 and 1.
*/
public void setAlpha(float alpha) {
this.alpha = alpha;
update();
}
/**
* Set this {@link MultiPoint}s alpha.
*
* @param alpha float value between 0 and 1.
*/
public void setAlpha(float alpha) {
this.alpha = alpha;
update();
}
abstract void update();
abstract void update();
}

View File

@@ -9,56 +9,56 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public final class Polygon extends MultiPoint {
private int fillColor = Color.BLACK; // default fillColor is black
private int strokeColor = Color.BLACK; // default strokeColor is black
private int fillColor = Color.BLACK; // default fillColor is black
private int strokeColor = Color.BLACK; // default strokeColor is black
Polygon() {
super();
}
Polygon() {
super();
}
/**
* Get the color of the fill region of the polygon.
*
* @return The color of the fill.
*/
public int getFillColor() {
return fillColor;
}
/**
* Get the color of the fill region of the polygon.
*
* @return The color of the fill.
*/
public int getFillColor() {
return fillColor;
}
/**
* Get the color fo the stroke of the polygon.
*
* @return The color of the stroke.
*/
public int getStrokeColor() {
return strokeColor;
}
/**
* Get the color fo the stroke of the polygon.
*
* @return The color of the stroke.
*/
public int getStrokeColor() {
return strokeColor;
}
/**
* Sets the color of the fill region of the polygon.
*
* @param color The color in ARGB format.
*/
public void setFillColor(int color) {
fillColor = color;
update();
}
/**
* Sets the color of the fill region of the polygon.
*
* @param color The color in ARGB format.
*/
public void setFillColor(int color) {
fillColor = color;
update();
}
/**
* Sets the color of the stroke of the polygon.
*
* @param color The color in ARGB format.
*/
public void setStrokeColor(int color) {
strokeColor = color;
update();
}
/**
* Sets the color of the stroke of the polygon.
*
* @param color The color in ARGB format.
*/
public void setStrokeColor(int color) {
strokeColor = color;
update();
}
@Override
void update() {
MapboxMap mapboxMap = getMapboxMap();
if (mapboxMap != null) {
mapboxMap.updatePolygon(this);
}
@Override
void update() {
MapboxMap mapboxMap = getMapboxMap();
if (mapboxMap != null) {
mapboxMap.updatePolygon(this);
}
}
}

View File

@@ -14,210 +14,220 @@ import java.util.List;
*/
public final class PolygonOptions implements Parcelable {
public static final Parcelable.Creator<PolygonOptions> CREATOR
= new Parcelable.Creator<PolygonOptions>() {
public PolygonOptions createFromParcel(Parcel in) {
return new PolygonOptions(in);
}
public static final Parcelable.Creator<PolygonOptions> CREATOR =
new Parcelable.Creator<PolygonOptions>() {
public PolygonOptions createFromParcel(Parcel in) {
return new PolygonOptions(in);
}
public PolygonOptions[] newArray(int size) {
return new PolygonOptions[size];
}
public PolygonOptions[] newArray(int size) {
return new PolygonOptions[size];
}
};
private PolygonOptions(Parcel in) {
polygon = new Polygon();
ArrayList<LatLng> pointsList = new ArrayList<>();
in.readList(pointsList, LatLng.class.getClassLoader());
addAll(pointsList);
alpha(in.readFloat());
fillColor(in.readInt());
strokeColor(in.readInt());
private PolygonOptions(Parcel in) {
polygon = new Polygon();
ArrayList<LatLng> pointsList = new ArrayList<>();
in.readList(pointsList, LatLng.class.getClassLoader());
addAll(pointsList);
alpha(in.readFloat());
fillColor(in.readInt());
strokeColor(in.readInt());
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeList(getPoints());
out.writeFloat(getAlpha());
out.writeInt(getFillColor());
out.writeInt(getStrokeColor());
}
private Polygon polygon;
/**
* Defines options for a polygon.
*/
public PolygonOptions() {
polygon = new Polygon();
}
/**
* Adds a vertex to the outline of the polygon being built.
*
* @param point {@link LatLng} point to be added to polygon geometry.
* @return This {@link PolygonOptions} object with the given point added to the outline.
*/
public PolygonOptions add(LatLng point) {
polygon.addPoint(point);
return this;
}
/**
* Adds vertices to the outline of the polygon being built.
*
* @param points {@link LatLng} points to be added to polygon geometry.
* @return This {@link PolygonOptions} object with the given points added to the outline.
*/
public PolygonOptions add(LatLng... points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Adds vertices to the outline of the polygon being built.
*
* @param points {@link Iterable} list made up of {@link LatLng} points defining the polygon
* geometry
* @return This {@link PolygonOptions} object with the given points added to the outline.
*/
public PolygonOptions addAll(Iterable<LatLng> points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Set the alpha value of the polyline.
*
* @param alpha float value between 0 (not visible) and 1.
* @return This {@link PolygonOptions} object with the given polygon alpha value.
*/
public PolygonOptions alpha(float alpha) {
polygon.setAlpha(alpha);
return this;
}
/**
* Gets the alpha set for this {@link PolygonOptions} object.
*
* @return float value between 0 and 1 defining the alpha.
*/
public float getAlpha() {
return polygon.getAlpha();
}
/**
* Specifies the polygon's fill color, as 32-bit ARGB. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolylineOptions} object with a new color set.
*/
public PolygonOptions fillColor(int color) {
polygon.setFillColor(color);
return this;
}
/**
* Gets the fill color set for this {@link PolygonOptions} object.
*
* @return The fill color of the polygon in ARGB format.
*/
public int getFillColor() {
return polygon.getFillColor();
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return Polygon the Polygon to return
*/
public Polygon getPolygon() {
return polygon;
}
/**
* Specifies the polygon's stroke color, as 32-bit ARGB. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolygonOptions} object with a new stroke color set.
*/
public PolygonOptions strokeColor(int color) {
polygon.setStrokeColor(color);
return this;
}
/**
* Gets the stroke color set for this {@link PolygonOptions} object.
*
* @return The stroke color of the polygon in ARGB format.
*/
public int getStrokeColor() {
return polygon.getStrokeColor();
}
public List<LatLng> getPoints() {
// the getter gives us a copy, which is the safe thing to do...
return polygon.getPoints();
}
/**
* Compares this {@link PolygonOptions} object with another {@link PolygonOptions} and
* determines if their color, alpha, stroke color, and vertices match.
*
* @param o Another {@link PolygonOptions} to compare with this object.
* @return True if color, alpha, stroke color, and vertices match this {@link PolygonOptions}
* object. Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
PolygonOptions polygon = (PolygonOptions) o;
if (Float.compare(polygon.getAlpha(), getAlpha()) != 0) {
return false;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeList(getPoints());
out.writeFloat(getAlpha());
out.writeInt(getFillColor());
out.writeInt(getStrokeColor());
if (getFillColor() != polygon.getFillColor()) {
return false;
}
private Polygon polygon;
/**
* Defines options for a polygon.
*/
public PolygonOptions() {
polygon = new Polygon();
if (getStrokeColor() != polygon.getStrokeColor()) {
return false;
}
return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null);
}
/**
* Adds a vertex to the outline of the polygon being built.
*
* @param point {@link LatLng} point to be added to polygon geometry.
* @return This {@link PolygonOptions} object with the given point added to the outline.
*/
public PolygonOptions add(LatLng point) {
polygon.addPoint(point);
return this;
}
/**
* Adds vertices to the outline of the polygon being built.
*
* @param points {@link LatLng} points to be added to polygon geometry.
* @return This {@link PolygonOptions} object with the given points added to the outline.
*/
public PolygonOptions add(LatLng... points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Adds vertices to the outline of the polygon being built.
*
* @param points {@link Iterable} list made up of {@link LatLng} points defining the polygon
* geometry
* @return This {@link PolygonOptions} object with the given points added to the outline.
*/
public PolygonOptions addAll(Iterable<LatLng> points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Set the alpha value of the polyline.
*
* @param alpha float value between 0 (not visible) and 1.
* @return This {@link PolygonOptions} object with the given polygon alpha value.
*/
public PolygonOptions alpha(float alpha) {
polygon.setAlpha(alpha);
return this;
}
/**
* Gets the alpha set for this {@link PolygonOptions} object.
*
* @return float value between 0 and 1 defining the alpha.
*/
public float getAlpha() {
return polygon.getAlpha();
}
/**
* Specifies the polygon's fill color, as 32-bit ARGB. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolylineOptions} object with a new color set.
*/
public PolygonOptions fillColor(int color) {
polygon.setFillColor(color);
return this;
}
/**
* Gets the fill color set for this {@link PolygonOptions} object.
*
* @return The fill color of the polygon in ARGB format.
*/
public int getFillColor() {
return polygon.getFillColor();
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return Polygon the Polygon to return
*/
public Polygon getPolygon() {
return polygon;
}
/**
* Specifies the polygon's stroke color, as 32-bit ARGB. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolygonOptions} object with a new stroke color set.
*/
public PolygonOptions strokeColor(int color) {
polygon.setStrokeColor(color);
return this;
}
/**
* Gets the stroke color set for this {@link PolygonOptions} object.
*
* @return The stroke color of the polygon in ARGB format.
*/
public int getStrokeColor() {
return polygon.getStrokeColor();
}
public List<LatLng> getPoints() {
// the getter gives us a copy, which is the safe thing to do...
return polygon.getPoints();
}
/**
* Compares this {@link PolygonOptions} object with another {@link PolygonOptions} and
* determines if their color, alpha, stroke color, and vertices match.
*
* @param o Another {@link PolygonOptions} to compare with this object.
* @return True if color, alpha, stroke color, and vertices match this {@link PolygonOptions}
* object. Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PolygonOptions polygon = (PolygonOptions) o;
if (Float.compare(polygon.getAlpha(), getAlpha()) != 0) return false;
if (getFillColor() != polygon.getFillColor()) return false;
if (getStrokeColor() != polygon.getStrokeColor()) return false;
return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null);
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
result = 31 * result + getFillColor();
result = 31 * result + getStrokeColor();
result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
return result;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
result = 31 * result + getFillColor();
result = 31 * result + getStrokeColor();
result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
return result;
}
}

View File

@@ -9,56 +9,56 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public final class Polyline extends MultiPoint {
private int color = Color.BLACK; // default color is black
private float width = 10; // As specified by Google API Docs (in pixels)
private int color = Color.BLACK; // default color is black
private float width = 10; // As specified by Google API Docs (in pixels)
Polyline() {
super();
}
Polyline() {
super();
}
/**
* Gets the color of this polyline.
*
* @return The color in ARGB format.
*/
public int getColor() {
return color;
}
/**
* Gets the color of this polyline.
*
* @return The color in ARGB format.
*/
public int getColor() {
return color;
}
/**
* Gets the width of this polyline.
*
* @return The width in screen pixels.
*/
public float getWidth() {
return width;
}
/**
* Gets the width of this polyline.
*
* @return The width in screen pixels.
*/
public float getWidth() {
return width;
}
/**
* Sets the color of the polyline.
*
* @param color - the color in ARGB format
*/
public void setColor(int color) {
this.color = color;
update();
}
/**
* Sets the color of the polyline.
*
* @param color - the color in ARGB format
*/
public void setColor(int color) {
this.color = color;
update();
}
/**
* Sets the width of the polyline.
*
* @param width in pixels
*/
public void setWidth(float width) {
this.width = width;
update();
}
/**
* Sets the width of the polyline.
*
* @param width in pixels
*/
public void setWidth(float width) {
this.width = width;
update();
}
@Override
void update() {
MapboxMap mapboxMap = getMapboxMap();
if (mapboxMap != null) {
mapboxMap.updatePolyline(this);
}
@Override
void update() {
MapboxMap mapboxMap = getMapboxMap();
if (mapboxMap != null) {
mapboxMap.updatePolyline(this);
}
}
}

View File

@@ -14,215 +14,225 @@ import java.util.List;
public final class PolylineOptions implements Parcelable {
public static final Parcelable.Creator<PolylineOptions> CREATOR
= new Parcelable.Creator<PolylineOptions>() {
public PolylineOptions createFromParcel(Parcel in) {
return new PolylineOptions(in);
}
public static final Parcelable.Creator<PolylineOptions> CREATOR =
new Parcelable.Creator<PolylineOptions>() {
public PolylineOptions createFromParcel(Parcel in) {
return new PolylineOptions(in);
}
public PolylineOptions[] newArray(int size) {
return new PolylineOptions[size];
}
public PolylineOptions[] newArray(int size) {
return new PolylineOptions[size];
}
};
private PolylineOptions(Parcel in) {
polyline = new Polyline();
ArrayList<LatLng> pointsList = new ArrayList<>();
in.readList(pointsList, LatLng.class.getClassLoader());
addAll(pointsList);
alpha(in.readFloat());
color(in.readInt());
width(in.readFloat());
private PolylineOptions(Parcel in) {
polyline = new Polyline();
ArrayList<LatLng> pointsList = new ArrayList<>();
in.readList(pointsList, LatLng.class.getClassLoader());
addAll(pointsList);
alpha(in.readFloat());
color(in.readInt());
width(in.readFloat());
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeList(getPoints());
out.writeFloat(getAlpha());
out.writeInt(getColor());
out.writeFloat(getWidth());
}
private Polyline polyline;
/**
* Defines options for a polyline.
*/
public PolylineOptions() {
polyline = new Polyline();
}
/**
* Adds a vertex to the end of the polyline being built.
*
* @param point {@link LatLng} point to be added to polyline geometry.
* @return This {@link PolylineOptions} object with the given point on the end.
*/
public PolylineOptions add(LatLng point) {
polyline.addPoint(point);
return this;
}
/**
* Adds vertices to the end of the polyline being built.
*
* @param points {@link LatLng} points defining the polyline geometry.
* @return This {@link PolylineOptions} object with the given point on the end.
*/
public PolylineOptions add(LatLng... points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Adds vertices to the end of the polyline being built.
*
* @param points {@link Iterable} list made up of {@link LatLng} points defining the polyline
* geometry
* @return This {@link PolylineOptions} object with the given points on the end.
*/
public PolylineOptions addAll(Iterable<LatLng> points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Set the alpha value of the polyline.
*
* @param alpha float value between 0 (not visible) and 1.
* @return This {@link PolylineOptions} object with the given polyline alpha value.
*/
public PolylineOptions alpha(float alpha) {
polyline.setAlpha(alpha);
return this;
}
/**
* Gets the alpha set for this {@link PolylineOptions} object.
*
* @return float value between 0 and 1 defining the alpha.
*/
public float getAlpha() {
return polyline.getAlpha();
}
/**
* Sets the color of the polyline as a 32-bit ARGB color. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolylineOptions} object with a new color set.
*/
public PolylineOptions color(int color) {
polyline.setColor(color);
return this;
}
/**
* Gets the color set for this {@link PolylineOptions} object.
*
* @return The color of the polyline in ARGB format.
*/
public int getColor() {
return polyline.getColor();
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return PolyLine The polyline build by this class.
*/
public Polyline getPolyline() {
return polyline;
}
/**
* Gets the width set for this {@link PolylineOptions} object.
*
* @return The width of the polyline in screen pixels.
*/
public float getWidth() {
return polyline.getWidth();
}
/**
* Sets the width of the polyline in screen pixels. The default is 10.
*
* @param width float value defining width of polyline using unit pixels.
* @return This {@link PolylineOptions} object with a new width set.
*/
public PolylineOptions width(float width) {
polyline.setWidth(width);
return this;
}
/**
* Gets the points set for this {@link PolylineOptions} object.
*
* @return a {@link List} of {@link LatLng}s specifying the vertices of the polyline.
*/
public List<LatLng> getPoints() {
// the getter gives us a copy, which is the safe thing to do...
return polyline.getPoints();
}
/**
* Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
* determines if their color, alpha, width, and vertices match.
*
* @param o Another {@link PolylineOptions} to compare with this object.
* @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
PolylineOptions polyline = (PolylineOptions) o;
if (Float.compare(polyline.getAlpha(), getAlpha()) != 0) {
return false;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeList(getPoints());
out.writeFloat(getAlpha());
out.writeInt(getColor());
out.writeFloat(getWidth());
if (getColor() != polyline.getColor()) {
return false;
}
private Polyline polyline;
/**
* Defines options for a polyline.
*/
public PolylineOptions() {
polyline = new Polyline();
if (Float.compare(polyline.getWidth(), getWidth()) != 0) {
return false;
}
return !(getPoints() != null ? !getPoints().equals(polyline.getPoints()) : polyline.getPoints() != null);
}
/**
* Adds a vertex to the end of the polyline being built.
*
* @param point {@link LatLng} point to be added to polyline geometry.
* @return This {@link PolylineOptions} object with the given point on the end.
*/
public PolylineOptions add(LatLng point) {
polyline.addPoint(point);
return this;
}
/**
* Adds vertices to the end of the polyline being built.
*
* @param points {@link LatLng} points defining the polyline geometry.
* @return This {@link PolylineOptions} object with the given point on the end.
*/
public PolylineOptions add(LatLng... points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Adds vertices to the end of the polyline being built.
*
* @param points {@link Iterable} list made up of {@link LatLng} points defining the polyline
* geometry
* @return This {@link PolylineOptions} object with the given points on the end.
*/
public PolylineOptions addAll(Iterable<LatLng> points) {
for (LatLng point : points) {
add(point);
}
return this;
}
/**
* Set the alpha value of the polyline.
*
* @param alpha float value between 0 (not visible) and 1.
* @return This {@link PolylineOptions} object with the given polyline alpha value.
*/
public PolylineOptions alpha(float alpha) {
polyline.setAlpha(alpha);
return this;
}
/**
* Gets the alpha set for this {@link PolylineOptions} object.
*
* @return float value between 0 and 1 defining the alpha.
*/
public float getAlpha() {
return polyline.getAlpha();
}
/**
* Sets the color of the polyline as a 32-bit ARGB color. The default color is black.
*
* @param color 32-bit ARGB color.
* @return This {@link PolylineOptions} object with a new color set.
*/
public PolylineOptions color(int color) {
polyline.setColor(color);
return this;
}
/**
* Gets the color set for this {@link PolylineOptions} object.
*
* @return The color of the polyline in ARGB format.
*/
public int getColor() {
return polyline.getColor();
}
/**
* Do not use this method. Used internally by the SDK.
*
* @return PolyLine The polyline build by this class.
*/
public Polyline getPolyline() {
return polyline;
}
/**
* Gets the width set for this {@link PolylineOptions} object.
*
* @return The width of the polyline in screen pixels.
*/
public float getWidth() {
return polyline.getWidth();
}
/**
* Sets the width of the polyline in screen pixels. The default is 10.
*
* @param width float value defining width of polyline using unit pixels.
* @return This {@link PolylineOptions} object with a new width set.
*/
public PolylineOptions width(float width) {
polyline.setWidth(width);
return this;
}
/**
* Gets the points set for this {@link PolylineOptions} object.
*
* @return a {@link List} of {@link LatLng}s specifying the vertices of the polyline.
*/
public List<LatLng> getPoints() {
// the getter gives us a copy, which is the safe thing to do...
return polyline.getPoints();
}
/**
* Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
* determines if their color, alpha, width, and vertices match.
*
* @param o Another {@link PolylineOptions} to compare with this object.
* @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PolylineOptions polyline = (PolylineOptions) o;
if (Float.compare(polyline.getAlpha(), getAlpha()) != 0) return false;
if (getColor() != polyline.getColor()) return false;
if (Float.compare(polyline.getWidth(), getWidth()) != 0) return false;
return !(getPoints() != null ? !getPoints().equals(polyline.getPoints()) : polyline.getPoints() != null);
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
result = 31 * result + getColor();
result = 31 * result + (getWidth() != +0.0f ? Float.floatToIntBits(getWidth()) : 0);
result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
return result;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
result = 31 * result + getColor();
result = 31 * result + (getWidth() != +0.0f ? Float.floatToIntBits(getWidth()) : 0);
result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
return result;
}
}

View File

@@ -16,304 +16,304 @@ import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing;
*/
public final class CameraPosition implements Parcelable {
public static final CameraPosition DEFAULT = new CameraPosition(new LatLng(), 0, 0, 0);
public static final CameraPosition DEFAULT = new CameraPosition(new LatLng(), 0, 0, 0);
public static final Parcelable.Creator<CameraPosition> CREATOR
= new Parcelable.Creator<CameraPosition>() {
public CameraPosition createFromParcel(Parcel in) {
double bearing = in.readDouble();
LatLng target = in.readParcelable(LatLng.class.getClassLoader());
double tilt = in.readDouble();
double zoom = in.readDouble();
return new CameraPosition(target, zoom, tilt, bearing);
}
public static final Parcelable.Creator<CameraPosition> CREATOR =
new Parcelable.Creator<CameraPosition>() {
public CameraPosition createFromParcel(Parcel in) {
double bearing = in.readDouble();
LatLng target = in.readParcelable(LatLng.class.getClassLoader());
double tilt = in.readDouble();
double zoom = in.readDouble();
return new CameraPosition(target, zoom, tilt, bearing);
}
public CameraPosition[] newArray(int size) {
return new CameraPosition[size];
}
public CameraPosition[] newArray(int size) {
return new CameraPosition[size];
}
};
/**
* Direction that the camera is pointing in, in degrees clockwise from north.
*/
public final double bearing;
/**
* Direction that the camera is pointing in, in degrees clockwise from north.
*/
public final double bearing;
/**
* The location that the camera is pointing at.
*/
public final LatLng target;
/**
* The angle, in degrees, of the camera angle from the nadir (directly facing the Earth).
* See tilt(float) for details of restrictions on the range of values.
*/
public final double tilt;
/**
* Zoom level near the center of the screen. See zoom(float) for the definition of the camera's
* zoom level.
*/
public final double zoom;
/**
* Constructs a CameraPosition.
*
* @param target The target location to align with the center of the screen.
* @param zoom Zoom level at target. See zoom(float) for details of restrictions.
* @param tilt The camera angle, in degrees, from the nadir (directly down). See tilt(float)
* for details of restrictions.
* @param bearing Direction that the camera is pointing in, in degrees clockwise from north.
* This value will be normalized to be within 0 degrees inclusive and 360 degrees
* exclusive.
* @throws NullPointerException if target is null
* @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive.
*/
CameraPosition(LatLng target, double zoom, double tilt, double bearing) {
this.target = target;
this.bearing = bearing;
this.tilt = tilt;
this.zoom = zoom;
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return integer 0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Flatten this object in to a Parcel.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(bearing);
out.writeParcelable(target, flags);
out.writeDouble(tilt);
out.writeDouble(zoom);
}
/**
* Returns a String with the camera target, zoom, bearing and tilt.
*
* @return A String with CameraPosition information.
*/
@Override
public String toString() {
return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt;
}
/**
* Compares this {@link CameraPosition} object with another {@link CameraPosition} and
* determines if their target, zoom, tilt, and bearing match.
*
* @param o Another {@link CameraPosition} to compare with this object.
* @return True if target, zoom, tilt, and bearing match this {@link CameraPosition} object.
* Else, false.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CameraPosition cameraPosition = (CameraPosition) o;
if (target != null && !target.equals(cameraPosition.target)) {
return false;
} else if (zoom != cameraPosition.zoom) {
return false;
} else if (tilt != cameraPosition.tilt) {
return false;
} else if (bearing != cameraPosition.bearing) {
return false;
}
return true;
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
*
* @return integer value you can use for storing element.
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (target != null ? target.hashCode() : 0);
return result;
}
/**
* Builder for composing {@link CameraPosition} objects.
*/
public static final class Builder {
private double bearing = -1;
private LatLng target = null;
private double tilt = -1;
private double zoom = -1;
/**
* The location that the camera is pointing at.
* Creates an empty builder.
*/
public final LatLng target;
public Builder() {
super();
}
/**
* The angle, in degrees, of the camera angle from the nadir (directly facing the Earth).
* See tilt(float) for details of restrictions on the range of values.
*/
public final double tilt;
/**
* Zoom level near the center of the screen. See zoom(float) for the definition of the camera's
* zoom level.
*/
public final double zoom;
/**
* Constructs a CameraPosition.
* Create Builder with an existing CameraPosition data.
*
* @param target The target location to align with the center of the screen.
* @param zoom Zoom level at target. See zoom(float) for details of restrictions.
* @param tilt The camera angle, in degrees, from the nadir (directly down). See tilt(float)
* for details of restrictions.
* @param bearing Direction that the camera is pointing in, in degrees clockwise from north.
* This value will be normalized to be within 0 degrees inclusive and 360 degrees
* exclusive.
* @throws NullPointerException if target is null
* @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive.
* @param previous Existing CameraPosition values to use
*/
CameraPosition(LatLng target, double zoom, double tilt, double bearing) {
this.target = target;
this.bearing = bearing;
this.tilt = tilt;
this.zoom = zoom;
public Builder(CameraPosition previous) {
super();
if (previous != null) {
this.bearing = previous.bearing;
this.target = previous.target;
this.tilt = previous.tilt;
this.zoom = previous.zoom;
}
}
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
* Create Builder with an existing CameraPosition data.
*
* @return integer 0.
* @param typedArray TypedArray containgin attribute values
*/
@Override
public int describeContents() {
return 0;
public Builder(TypedArray typedArray) {
super();
if (typedArray != null) {
this.bearing = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraBearing, 0.0f);
double lat = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLat, 0.0f);
double lng = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLng, 0.0f);
this.target = new LatLng(lat, lng);
this.tilt = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTilt, 0.0f);
this.zoom = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoom, 0.0f);
}
}
/**
* Flatten this object in to a Parcel.
* Create Builder from an existing CameraPositionUpdate update.
*
* @param out The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written. May be 0 or
* {@link #PARCELABLE_WRITE_RETURN_VALUE}.
* @param update Update containing camera options
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(bearing);
out.writeParcelable(target, flags);
out.writeDouble(tilt);
out.writeDouble(zoom);
public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
super();
if (update != null) {
bearing = update.getBearing();
target = update.getTarget();
tilt = update.getTilt();
zoom = update.getZoom();
}
}
/**
* Returns a String with the camera target, zoom, bearing and tilt.
* Create Builder from an existing CameraPositionUpdate update.
*
* @return A String with CameraPosition information.
* @param update Update containing camera options
*/
@Override
public String toString() {
return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt;
public Builder(CameraUpdateFactory.ZoomUpdate update) {
super();
if (update != null) {
this.zoom = update.getZoom();
}
}
/**
* Compares this {@link CameraPosition} object with another {@link CameraPosition} and
* determines if their target, zoom, tilt, and bearing match.
* Create Builder from an existing array of doubles.
* <p>
* These values conform to map.ccp representation of a camera position.
* </p>
*
* @param o Another {@link CameraPosition} to compare with this object.
* @return True if target, zoom, tilt, and bearing match this {@link CameraPosition} object.
* Else, false.
* @param nativeCameraValues Values containing target, bearing, tilt and zoom
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CameraPosition cameraPosition = (CameraPosition) o;
if (target != null && !target.equals(cameraPosition.target)) {
return false;
} else if (zoom != cameraPosition.zoom) {
return false;
} else if (tilt != cameraPosition.tilt) {
return false;
} else if (bearing != cameraPosition.bearing) {
return false;
}
return true;
public Builder(double[] nativeCameraValues) {
super();
if (nativeCameraValues != null && nativeCameraValues.length == 5) {
target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
bearing(convertNativeBearing(nativeCameraValues[2]));
tilt(nativeCameraValues[3]);
zoom(nativeCameraValues[4]);
}
}
/**
* Gives an integer which can be used as the bucket number for storing elements of the set/map.
* This bucket number is the address of the element inside the set/map. There's no guarantee
* that this hash value will be consistent between different Java implementations, or even
* between different execution runs of the same program.
* Sets the direction that the camera is pointing in, in degrees clockwise from north.
*
* @return integer value you can use for storing element.
* @param bearing Bearing
* @return Builder
*/
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (target != null ? target.hashCode() : 0);
return result;
public Builder bearing(double bearing) {
double direction = bearing;
while (direction >= 360) {
direction -= 360;
}
while (direction < 0) {
direction += 360;
}
this.bearing = direction;
return this;
}
/**
* Builder for composing {@link CameraPosition} objects.
* Builds a CameraPosition.
*
* @return CameraPosition
*/
public static final class Builder {
private double bearing = -1;
private LatLng target = null;
private double tilt = -1;
private double zoom = -1;
/**
* Creates an empty builder.
*/
public Builder() {
super();
}
/**
* Create Builder with an existing CameraPosition data.
*
* @param previous Existing CameraPosition values to use
*/
public Builder(CameraPosition previous) {
super();
if (previous != null) {
this.bearing = previous.bearing;
this.target = previous.target;
this.tilt = previous.tilt;
this.zoom = previous.zoom;
}
}
/**
* Create Builder with an existing CameraPosition data.
*
* @param typedArray TypedArray containgin attribute values
*/
public Builder(TypedArray typedArray) {
super();
if (typedArray != null) {
this.bearing = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraBearing, 0.0f);
double lat = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLat, 0.0f);
double lng = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLng, 0.0f);
this.target = new LatLng(lat, lng);
this.tilt = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTilt, 0.0f);
this.zoom = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoom, 0.0f);
}
}
/**
* Create Builder from an existing CameraPositionUpdate update.
*
* @param update Update containing camera options
*/
public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
super();
if (update != null) {
bearing = update.getBearing();
target = update.getTarget();
tilt = update.getTilt();
zoom = update.getZoom();
}
}
/**
* Create Builder from an existing CameraPositionUpdate update.
*
* @param update Update containing camera options
*/
public Builder(CameraUpdateFactory.ZoomUpdate update) {
super();
if (update != null) {
this.zoom = update.getZoom();
}
}
/**
* Create Builder from an existing array of doubles.
* <p>
* These values conform to map.ccp representation of a camera position.
* </p>
*
* @param nativeCameraValues Values containing target, bearing, tilt and zoom
*/
public Builder(double[] nativeCameraValues) {
super();
if (nativeCameraValues != null && nativeCameraValues.length == 5) {
target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
bearing(convertNativeBearing(nativeCameraValues[2]));
tilt(nativeCameraValues[3]);
zoom(nativeCameraValues[4]);
}
}
/**
* Sets the direction that the camera is pointing in, in degrees clockwise from north.
*
* @param bearing Bearing
* @return Builder
*/
public Builder bearing(double bearing) {
double direction = bearing;
while (direction >= 360) {
direction -= 360;
}
while (direction < 0) {
direction += 360;
}
this.bearing = direction;
return this;
}
/**
* Builds a CameraPosition.
*
* @return CameraPosition
*/
public CameraPosition build() {
return new CameraPosition(target, zoom, tilt, bearing);
}
/**
* Sets the location that the camera is pointing at.
*
* @param location Location
* @return Builder
*/
public Builder target(LatLng location) {
this.target = location;
return this;
}
/**
* Set the tilt in degrees
* <p>
* value is clamped to 0 and 60.
* <p/>
*
* @param tilt Tilt value
* @return Builder
*/
public Builder tilt(double tilt) {
this.tilt = MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT);
return this;
}
/**
* Set the zoom
*
* @param zoom Zoom value
* @return Builder
*/
public Builder zoom(double zoom) {
this.zoom = zoom;
return this;
}
public CameraPosition build() {
return new CameraPosition(target, zoom, tilt, bearing);
}
/**
* Sets the location that the camera is pointing at.
*
* @param location Location
* @return Builder
*/
public Builder target(LatLng location) {
this.target = location;
return this;
}
/**
* Set the tilt in degrees
* <p>
* value is clamped to 0 and 60.
* <p/>
*
* @param tilt Tilt value
* @return Builder
*/
public Builder tilt(double tilt) {
this.tilt = MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT);
return this;
}
/**
* Set the zoom
*
* @param zoom Zoom value
* @return Builder
*/
public Builder zoom(double zoom) {
this.zoom = zoom;
return this;
}
}
}

View File

@@ -9,6 +9,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public interface CameraUpdate {
CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap);
CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap);
}

View File

@@ -21,395 +21,397 @@ import java.lang.annotation.RetentionPolicy;
*/
public final class CameraUpdateFactory {
/**
* Returns a CameraUpdate that moves the camera to a specified CameraPosition.
*
* @param cameraPosition Camera Position to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
/**
* Returns a CameraUpdate that moves the camera to a specified CameraPosition.
*
* @param cameraPosition Camera Position to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt,
cameraPosition.zoom);
}
/**
* Returns a CameraUpdate that 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
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLng(@NonNull LatLng latLng) {
return new CameraPositionUpdate(-1, latLng, -1, -1);
}
/**
* Returns a {@link CameraUpdate} that transforms the camera such that the specified
* latitude/longitude bounds are centered on screen at the greatest possible zoom level.
* You can specify padding, in order to inset the bounding box from the map view's edges.
* The returned CameraUpdate has a bearing of 0 and a tilt of 0.
*
* @param bounds Bounds to match Camera position with
* @param padding Padding added to the bounds
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int padding) {
return newLatLngBounds(bounds, padding, padding, padding, padding);
}
/**
* Returns a {@link CameraUpdate} that transforms the camera such that the specified
* latitude/longitude bounds are centered on screen at the greatest possible zoom level.
* You can specify padding, in order to inset the bounding box from the map view's edges.
* The returned CameraUpdate has a bearing of 0 and a tilt of 0.
*
* @param bounds Bounds to base the Camera position out of
* @param paddingLeft Padding left of the bounds
* @param paddingTop Padding top of the bounds
* @param paddingRight Padding right of the bounds
* @param paddingBottom Padding bottom of the bounds
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int paddingLeft, int paddingTop,
int paddingRight, int paddingBottom) {
return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
}
/**
* Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
* specified by a LatLng object, and moves to the given zoom level.
*
* @param latLng Target location to change to
* @param zoom Zoom level to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, double zoom) {
return new CameraPositionUpdate(-1, latLng, -1, zoom);
}
/**
* Returns a CameraUpdate that scrolls the camera over the map,
* shifting the center of view by the specified number of pixels in the x and y directions.
*
* @param xPixel Amount of pixels to scroll to in x direction
* @param yPixel Amount of pixels to scroll to in y direction
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate scrollBy(float xPixel, float yPixel) {
return new CameraMoveUpdate(xPixel, yPixel);
}
/**
* Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
*
* @param amount Amount of zoom level to change with
* @param focus Focus point of zoom
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomBy(double amount, Point focus) {
return new ZoomUpdate(amount, focus.x, focus.y);
}
/**
* Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
*
* @param amount Amount of zoom level to change with
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomBy(double amount) {
return new ZoomUpdate(ZoomUpdate.ZOOM_BY, amount);
}
/**
* Returns a CameraUpdate that zooms in on the map by moving the viewpoint's height closer to
* the Earth's surface. The zoom increment is 1.0.
*
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomIn() {
return new ZoomUpdate(ZoomUpdate.ZOOM_IN);
}
/**
* Returns a CameraUpdate that zooms out on the map by moving the viewpoint's height farther
* away from the Earth's surface. The zoom increment is -1.0.
*
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomOut() {
return new ZoomUpdate(ZoomUpdate.ZOOM_OUT);
}
/**
* Returns a CameraUpdate that moves the camera viewpoint to a particular zoom level.
*
* @param zoom Zoom level to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomTo(double zoom) {
return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
}
//
// CameraUpdate types
//
static final class CameraPositionUpdate implements CameraUpdate {
private final double bearing;
private final LatLng target;
private final double tilt;
private final double zoom;
CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom) {
this.bearing = bearing;
this.target = target;
this.tilt = tilt;
this.zoom = zoom;
}
public LatLng getTarget() {
return target;
}
public double getBearing() {
return bearing;
}
public double getTilt() {
return tilt;
}
public double getZoom() {
return zoom;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
CameraPosition previousPosition = mapboxMap.getCameraPosition();
if (target == null) {
return new CameraPosition.Builder(this)
.target(previousPosition.target)
.build();
}
return new CameraPosition.Builder(this).build();
}
}
static final class CameraBoundsUpdate implements CameraUpdate {
private LatLngBounds bounds;
private RectF padding;
CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
this.bounds = bounds;
this.padding = padding;
}
CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}
CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
this(bounds, new int[] {paddingLeft, paddingTop, paddingRight, paddingBottom});
}
public LatLngBounds getBounds() {
return bounds;
}
public RectF getPadding() {
return padding;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
// Get required objects
Projection projection = mapboxMap.getProjection();
UiSettings uiSettings = mapboxMap.getUiSettings();
// calculate correct padding
int[] mapPadding = mapboxMap.getPadding();
RectF latLngPadding = getPadding();
RectF padding = new RectF(latLngPadding.left + mapPadding[0],
latLngPadding.top + mapPadding[1],
latLngPadding.right + mapPadding[2],
latLngPadding.bottom + mapPadding[3]);
// Calculate the bounds of the possibly rotated shape with respect to the viewport
PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE);
PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE);
float viewportHeight = uiSettings.getHeight();
for (LatLng latLng : getBounds().toLatLngs()) {
PointF pixel = projection.toScreenLocation(latLng);
swPixel.x = Math.min(swPixel.x, pixel.x);
nePixel.x = Math.max(nePixel.x, pixel.x);
swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
}
// Calculate width/height
float width = nePixel.x - swPixel.x;
float height = nePixel.y - swPixel.y;
double zoom = 0;
float minScale = 1;
// Calculate the zoom level
if (padding != null) {
float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
minScale = scaleX < scaleY ? scaleX : scaleY;
zoom = calculateZoom(mapboxMap, minScale);
zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel());
}
// Calculate the center point
PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
centerPixel.y = viewportHeight - centerPixel.y;
LatLng center = projection.fromScreenLocation(centerPixel);
return new CameraPosition.Builder()
.target(center)
.zoom(zoom)
.tilt(0)
.bearing(0)
.build();
}
/**
* Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
* specified by a LatLng object. This centers the camera on the LatLng object.
* Calculates a zoom level based on minimum scale and current scale from MapView
*
* @param latLng Target location to change to
* @return CameraUpdate Final Camera Position
* @param minScale The minimum scale to calculate the zoom level.
* @return zoom level that fits the MapView.
*/
public static CameraUpdate newLatLng(@NonNull LatLng latLng) {
return new CameraPositionUpdate(-1, latLng, -1, -1);
public double calculateZoom(MapboxMap mapboxMap, float minScale) {
return Math.log(mapboxMap.getCameraPosition().zoom * minScale) / Math.log(2);
}
}
static final class CameraMoveUpdate implements CameraUpdate {
private float x;
private float y;
CameraMoveUpdate(float x, float y) {
this.x = x;
this.y = y;
}
/**
* Returns a {@link CameraUpdate} that transforms the camera such that the specified
* latitude/longitude bounds are centered on screen at the greatest possible zoom level.
* You can specify padding, in order to inset the bounding box from the map view's edges.
* The returned CameraUpdate has a bearing of 0 and a tilt of 0.
*
* @param bounds Bounds to match Camera position with
* @param padding Padding added to the bounds
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int padding) {
return newLatLngBounds(bounds, padding, padding, padding, padding);
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
UiSettings uiSettings = mapboxMap.getUiSettings();
Projection projection = mapboxMap.getProjection();
// Calculate the new center point
float viewPortWidth = uiSettings.getWidth();
float viewPortHeight = uiSettings.getHeight();
PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
// Convert point to LatLng
LatLng latLng = projection.fromScreenLocation(targetPoint);
CameraPosition previousPosition = mapboxMap.getCameraPosition();
return new CameraPosition.Builder()
.target(latLng != null ? latLng : previousPosition.target)
.zoom(previousPosition.zoom)
.tilt(previousPosition.tilt)
.bearing(previousPosition.bearing)
.build();
}
}
static final class ZoomUpdate implements CameraUpdate {
@IntDef( {ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
@Retention(RetentionPolicy.SOURCE)
@interface Type {
}
/**
* Returns a {@link CameraUpdate} that transforms the camera such that the specified
* latitude/longitude bounds are centered on screen at the greatest possible zoom level.
* You can specify padding, in order to inset the bounding box from the map view's edges.
* The returned CameraUpdate has a bearing of 0 and a tilt of 0.
*
* @param bounds Bounds to base the Camera position out of
* @param paddingLeft Padding left of the bounds
* @param paddingTop Padding top of the bounds
* @param paddingRight Padding right of the bounds
* @param paddingBottom Padding bottom of the bounds
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
static final int ZOOM_IN = 0;
static final int ZOOM_OUT = 1;
static final int ZOOM_BY = 2;
static final int ZOOM_TO = 3;
static final int ZOOM_TO_POINT = 4;
@Type
private final int type;
private final double zoom;
private float x;
private float y;
ZoomUpdate(@Type int type) {
this.type = type;
this.zoom = 0;
}
/**
* Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
* specified by a LatLng object, and moves to the given zoom level.
*
* @param latLng Target location to change to
* @param zoom Zoom level to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, double zoom) {
return new CameraPositionUpdate(-1, latLng, -1, zoom);
ZoomUpdate(@Type int type, double zoom) {
this.type = type;
this.zoom = zoom;
}
/**
* Returns a CameraUpdate that scrolls the camera over the map,
* shifting the center of view by the specified number of pixels in the x and y directions.
*
* @param xPixel Amount of pixels to scroll to in x direction
* @param yPixel Amount of pixels to scroll to in y direction
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate scrollBy(float xPixel, float yPixel) {
return new CameraMoveUpdate(xPixel, yPixel);
ZoomUpdate(double zoom, float x, float y) {
this.type = ZOOM_TO_POINT;
this.zoom = zoom;
this.x = x;
this.y = y;
}
/**
* Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
*
* @param amount Amount of zoom level to change with
* @param focus Focus point of zoom
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomBy(double amount, Point focus) {
return new ZoomUpdate(amount, focus.x, focus.y);
public double getZoom() {
return zoom;
}
/**
* Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
*
* @param amount Amount of zoom level to change with
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomBy(double amount) {
return new ZoomUpdate(ZoomUpdate.ZOOM_BY, amount);
@Type
public int getType() {
return type;
}
/**
* Returns a CameraUpdate that zooms in on the map by moving the viewpoint's height closer to
* the Earth's surface. The zoom increment is 1.0.
*
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomIn() {
return new ZoomUpdate(ZoomUpdate.ZOOM_IN);
public float getX() {
return x;
}
/**
* Returns a CameraUpdate that zooms out on the map by moving the viewpoint's height farther
* away from the Earth's surface. The zoom increment is -1.0.
*
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomOut() {
return new ZoomUpdate(ZoomUpdate.ZOOM_OUT);
public float getY() {
return y;
}
/**
* Returns a CameraUpdate that moves the camera viewpoint to a particular zoom level.
*
* @param zoom Zoom level to change to
* @return CameraUpdate Final Camera Position
*/
public static CameraUpdate zoomTo(double zoom) {
return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
double transformZoom(double currentZoom) {
switch (getType()) {
case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
currentZoom++;
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_OUT:
currentZoom--;
if (currentZoom < 0) {
currentZoom = 0;
}
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_TO:
currentZoom = getZoom();
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_BY:
currentZoom = currentZoom + getZoom();
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT:
currentZoom = currentZoom + getZoom();
break;
}
return currentZoom;
}
//
// CameraUpdate types
//
static final class CameraPositionUpdate implements CameraUpdate {
private final double bearing;
private final LatLng target;
private final double tilt;
private final double zoom;
CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom) {
this.bearing = bearing;
this.target = target;
this.tilt = tilt;
this.zoom = zoom;
}
public LatLng getTarget() {
return target;
}
public double getBearing() {
return bearing;
}
public double getTilt() {
return tilt;
}
public double getZoom() {
return zoom;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
CameraPosition previousPosition = mapboxMap.getCameraPosition();
if (target == null) {
return new CameraPosition.Builder(this)
.target(previousPosition.target)
.build();
}
return new CameraPosition.Builder(this).build();
}
}
static final class CameraBoundsUpdate implements CameraUpdate {
private LatLngBounds bounds;
private RectF padding;
CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
this.bounds = bounds;
this.padding = padding;
}
CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}
CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
this(bounds, new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom});
}
public LatLngBounds getBounds() {
return bounds;
}
public RectF getPadding() {
return padding;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
// Get required objects
Projection projection = mapboxMap.getProjection();
UiSettings uiSettings = mapboxMap.getUiSettings();
// calculate correct padding
int[] mapPadding = mapboxMap.getPadding();
RectF latLngPadding = getPadding();
RectF padding = new RectF(latLngPadding.left + mapPadding[0],
latLngPadding.top + mapPadding[1],
latLngPadding.right + mapPadding[2],
latLngPadding.bottom + mapPadding[3]);
// Calculate the bounds of the possibly rotated shape with respect to the viewport
PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE);
PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE);
float viewportHeight = uiSettings.getHeight();
for (LatLng latLng : getBounds().toLatLngs()) {
PointF pixel = projection.toScreenLocation(latLng);
swPixel.x = Math.min(swPixel.x, pixel.x);
nePixel.x = Math.max(nePixel.x, pixel.x);
swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
}
// Calculate width/height
float width = nePixel.x - swPixel.x;
float height = nePixel.y - swPixel.y;
double zoom = 0;
float minScale = 1;
// Calculate the zoom level
if (padding != null) {
float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
minScale = scaleX < scaleY ? scaleX : scaleY;
zoom = calculateZoom(mapboxMap, minScale);
zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel());
}
// Calculate the center point
PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
centerPixel.y = viewportHeight - centerPixel.y;
LatLng center = projection.fromScreenLocation(centerPixel);
return new CameraPosition.Builder()
.target(center)
.zoom(zoom)
.tilt(0)
.bearing(0)
.build();
}
/**
* Calculates a zoom level based on minimum scale and current scale from MapView
*
* @param minScale The minimum scale to calculate the zoom level.
* @return zoom level that fits the MapView.
*/
public double calculateZoom(MapboxMap mapboxMap, float minScale) {
return Math.log(mapboxMap.getCameraPosition().zoom * minScale) / Math.log(2);
}
}
static final class CameraMoveUpdate implements CameraUpdate {
private float x;
private float y;
CameraMoveUpdate(float x, float y) {
this.x = x;
this.y = y;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
UiSettings uiSettings = mapboxMap.getUiSettings();
Projection projection = mapboxMap.getProjection();
// Calculate the new center point
float viewPortWidth = uiSettings.getWidth();
float viewPortHeight = uiSettings.getHeight();
PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
// Convert point to LatLng
LatLng latLng = projection.fromScreenLocation(targetPoint);
CameraPosition previousPosition = mapboxMap.getCameraPosition();
return new CameraPosition.Builder()
.target(latLng != null ? latLng : previousPosition.target)
.zoom(previousPosition.zoom)
.tilt(previousPosition.tilt)
.bearing(previousPosition.bearing)
.build();
}
}
static final class ZoomUpdate implements CameraUpdate {
@IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
@Retention(RetentionPolicy.SOURCE)
@interface Type {
}
static final int ZOOM_IN = 0;
static final int ZOOM_OUT = 1;
static final int ZOOM_BY = 2;
static final int ZOOM_TO = 3;
static final int ZOOM_TO_POINT = 4;
@Type
private final int type;
private final double zoom;
private float x;
private float y;
ZoomUpdate(@Type int type) {
this.type = type;
this.zoom = 0;
}
ZoomUpdate(@Type int type, double zoom) {
this.type = type;
this.zoom = zoom;
}
ZoomUpdate(double zoom, float x, float y) {
this.type = ZOOM_TO_POINT;
this.zoom = zoom;
this.x = x;
this.y = y;
}
public double getZoom() {
return zoom;
}
@Type
public int getType() {
return type;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
double transformZoom(double currentZoom) {
switch (getType()) {
case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
currentZoom++;
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_OUT:
currentZoom--;
if (currentZoom < 0) {
currentZoom = 0;
}
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_TO:
currentZoom = getZoom();
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_BY:
currentZoom = currentZoom + getZoom();
break;
case CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT:
currentZoom = currentZoom + getZoom();
break;
}
return currentZoom;
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
CameraPosition cameraPosition = mapboxMap.getCameraPosition();
if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) {
return new CameraPosition.Builder(cameraPosition)
.zoom(transformZoom(cameraPosition.zoom))
.build();
} else {
return new CameraPosition.Builder(cameraPosition)
.zoom(transformZoom(cameraPosition.zoom))
.target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY())))
.build();
}
}
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
CameraPosition cameraPosition = mapboxMap.getCameraPosition();
if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) {
return new CameraPosition.Builder(cameraPosition)
.zoom(transformZoom(cameraPosition.zoom))
.build();
} else {
return new CameraPosition.Builder(cameraPosition)
.zoom(transformZoom(cameraPosition.zoom))
.target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY())))
.build();
}
}
}
}

View File

@@ -5,34 +5,34 @@ package com.mapbox.mapboxsdk.constants;
*/
public class GeoConstants {
/**
* The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a>
* value in meters
*/
public static final int RADIUS_EARTH_METERS = 6378137;
/**
* The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a>
* value in meters
*/
public static final int RADIUS_EARTH_METERS = 6378137;
/**
* The minimum latitude on Earth. This is the minimum latitude representable
* by Mapbox GL's Mercator projection, because the projection distorts latitude
* near the poles towards infinity.
*/
public static final double MIN_LATITUDE = -85.05112878;
/**
* The minimum latitude on Earth. This is the minimum latitude representable
* by Mapbox GL's Mercator projection, because the projection distorts latitude
* near the poles towards infinity.
*/
public static final double MIN_LATITUDE = -85.05112878;
/**
* The maximum latitude on Earth. This is the maximum latitude representable
* by Mapbox GL's Mercator projection, because the projection distorts latitude
* near the poles towards infinity.
*/
public static final double MAX_LATITUDE = 85.05112878;
/**
* The maximum latitude on Earth. This is the maximum latitude representable
* by Mapbox GL's Mercator projection, because the projection distorts latitude
* near the poles towards infinity.
*/
public static final double MAX_LATITUDE = 85.05112878;
/**
* The minimum longitude on Earth
*/
public static final double MIN_LONGITUDE = -180;
/**
* The minimum longitude on Earth
*/
public static final double MIN_LONGITUDE = -180;
/**
* The maximum longitude on Earth
*/
public static final double MAX_LONGITUDE = 180;
/**
* The maximum longitude on Earth
*/
public static final double MAX_LONGITUDE = 180;
}

View File

@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.constants;
import android.content.Context;
import java.util.Locale;
/**
@@ -8,137 +9,140 @@ import java.util.Locale;
*/
public class MapboxConstants {
/**
* Default Locale for data processing (ex: String.toLowerCase(MAPBOX_LOCALE, "foo"))
*/
public static final Locale MAPBOX_LOCALE = Locale.US;
/**
* Default Locale for data processing (ex: String.toLowerCase(MAPBOX_LOCALE, "foo"))
*/
public static final Locale MAPBOX_LOCALE = Locale.US;
/**
* Key used to store access token in AndroidManifest.xml
* @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
public static final String KEY_META_DATA_MANIFEST = "com.mapbox.AccessToken";
/**
* Key used to store access token in AndroidManifest.xml
*
* @deprecated As of release 4.1.0, replaced by
* {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
public static final String KEY_META_DATA_MANIFEST = "com.mapbox.AccessToken";
/**
* Key used to store staging data server url in AndroidManifest.xml
*/
public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer";
/**
* Key used to store staging data server url in AndroidManifest.xml
*/
public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer";
/**
* Key used to store staging data server access token in AndroidManifest.xml
*/
public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
/**
* Key used to store staging data server access token in AndroidManifest.xml
*/
public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
/**
* Key used to switch storage to external in AndroidManifest.xml
*/
public final static String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
/**
* Key used to switch storage to external in AndroidManifest.xml
*/
public static final String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
/**
* Default value for KEY_META_DATA_SET_STORAGE_EXTERNAL (default is internal storage)
*/
public final static boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
/**
* Default value for KEY_META_DATA_SET_STORAGE_EXTERNAL (default is internal storage)
*/
public static final boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
/**
* Unmeasured state
*/
public final static float UNMEASURED = -1f;
/**
* Unmeasured state
*/
public static final float UNMEASURED = -1f;
/**
* Default animation time
*/
public static final int ANIMATION_DURATION = 300;
/**
* Default animation time
*/
public static final int ANIMATION_DURATION = 300;
/**
* Default short animation time
*/
public static final int ANIMATION_DURATION_SHORT = 150;
/**
* Default short animation time
*/
public static final int ANIMATION_DURATION_SHORT = 150;
/**
* Animation time of a fling gesture
*/
public static final long ANIMATION_DURATION_FLING = 350;
/**
* Animation time of a fling gesture
*/
public static final long ANIMATION_DURATION_FLING = 350;
/**
* The currently supported minimum zoom level.
*/
public static final float MINIMUM_ZOOM = 0.0f;
/**
* The currently supported minimum zoom level.
*/
public static final float MINIMUM_ZOOM = 0.0f;
/**
* The currently supported maximum zoom level.
*/
public static final float MAXIMUM_ZOOM = 20.0f;
/**
* The currently supported maximum zoom level.
*/
public static final float MAXIMUM_ZOOM = 20.0f;
/**
* The currently supported maximum tilt value.
*/
public static final double MAXIMUM_TILT = 60;
/**
* The currently supported maximum tilt value.
*/
public static final double MAXIMUM_TILT = 60;
/**
* The currently supported minimum tilt value.
*/
public static final double MINIMUM_TILT = 0;
/**
* The currently supported minimum tilt value.
*/
public static final double MINIMUM_TILT = 0;
/**
* The currently supported maximum direction
*/
public static final double MAXIMUM_DIRECTION = 360;
/**
* The currently supported maximum direction
*/
public static final double MAXIMUM_DIRECTION = 360;
/**
* The currently supported minimum direction
*/
public static final double MINIMUM_DIRECTION = 0;
/**
* The currently supported minimum direction
*/
public static final double MINIMUM_DIRECTION = 0;
/**
* Fragment Argument Key for MapboxMapOptions
*/
public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions";
/**
* Fragment Argument Key for MapboxMapOptions
*/
public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions";
// Save instance state keys
public static final String STATE_HAS_SAVED_STATE = "savedState";
public static final String STATE_CAMERA_POSITION = "cameraPosition";
public static final String STATE_ZOOM_ENABLED = "zoomEnabled";
public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange";
public static final String STATE_SCROLL_ENABLED = "scrollEnabled";
public static final String STATE_SCROLL_ENABLED_CHANGE = "scrollEnabledChange";
public static final String STATE_ROTATE_ENABLED = "rotateEnabled";
public static final String STATE_ROTATE_ENABLED_CHANGE = "rotateEnabledChange";
public static final String STATE_TILT_ENABLED = "tiltEnabled";
public static final String STATE_TILT_ENABLED_CHANGE = "tiltEnabledChange";
public static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled";
public static final String STATE_DEBUG_ACTIVE = "debugActive";
public static final String STATE_STYLE_URL = "styleUrl";
public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss";
public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss";
public static final String STATE_COMPASS_ENABLED = "compassEnabled";
public static final String STATE_COMPASS_GRAVITY = "compassGravity";
public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
public static final String STATE_COMPASS_MARGIN_TOP = "compassMarginTop";
public static final String STATE_COMPASS_MARGIN_RIGHT = "compassMarginRight";
public static final String STATE_COMPASS_MARGIN_BOTTOM = "compassMarginBottom";
public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "compassFade";
public static final String STATE_LOGO_GRAVITY = "logoGravity";
public static final String STATE_LOGO_MARGIN_LEFT = "logoMarginLeft";
public static final String STATE_LOGO_MARGIN_TOP = "logoMarginTop";
public static final String STATE_LOGO_MARGIN_RIGHT = "logoMarginRight";
public static final String STATE_LOGO_MARGIN_BOTTOM = "logoMarginBottom";
public static final String STATE_LOGO_ENABLED = "logoEnabled";
public static final String STATE_ATTRIBUTION_GRAVITY = "attrGravity";
public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "attrMarginLeft";
public static final String STATE_ATTRIBUTION_MARGIN_TOP = "attrMarginTop";
public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "attrMarginRight";
public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "atrrMarginBottom";
public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled";
// Save instance state keys
public static final String STATE_HAS_SAVED_STATE = "savedState";
public static final String STATE_CAMERA_POSITION = "cameraPosition";
public static final String STATE_ZOOM_ENABLED = "zoomEnabled";
public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange";
public static final String STATE_SCROLL_ENABLED = "scrollEnabled";
public static final String STATE_SCROLL_ENABLED_CHANGE = "scrollEnabledChange";
public static final String STATE_ROTATE_ENABLED = "rotateEnabled";
public static final String STATE_ROTATE_ENABLED_CHANGE = "rotateEnabledChange";
public static final String STATE_TILT_ENABLED = "tiltEnabled";
public static final String STATE_TILT_ENABLED_CHANGE = "tiltEnabledChange";
public static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled";
public static final String STATE_DEBUG_ACTIVE = "debugActive";
public static final String STATE_STYLE_URL = "styleUrl";
public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss";
public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss";
public static final String STATE_COMPASS_ENABLED = "compassEnabled";
public static final String STATE_COMPASS_GRAVITY = "compassGravity";
public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
public static final String STATE_COMPASS_MARGIN_TOP = "compassMarginTop";
public static final String STATE_COMPASS_MARGIN_RIGHT = "compassMarginRight";
public static final String STATE_COMPASS_MARGIN_BOTTOM = "compassMarginBottom";
public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "compassFade";
public static final String STATE_LOGO_GRAVITY = "logoGravity";
public static final String STATE_LOGO_MARGIN_LEFT = "logoMarginLeft";
public static final String STATE_LOGO_MARGIN_TOP = "logoMarginTop";
public static final String STATE_LOGO_MARGIN_RIGHT = "logoMarginRight";
public static final String STATE_LOGO_MARGIN_BOTTOM = "logoMarginBottom";
public static final String STATE_LOGO_ENABLED = "logoEnabled";
public static final String STATE_ATTRIBUTION_GRAVITY = "attrGravity";
public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "attrMarginLeft";
public static final String STATE_ATTRIBUTION_MARGIN_TOP = "attrMarginTop";
public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "attrMarginRight";
public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "atrrMarginBottom";
public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled";
public static final String TAG = "MapboxMap";
public static final String TAG = "MapboxMap";
public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN = "mapboxTelemetryStagingAccessToken";
public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl";
public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN =
"mapboxTelemetryStagingAccessToken";
}

View File

@@ -2,7 +2,6 @@ package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import java.lang.annotation.Retention;
@@ -11,34 +10,34 @@ import java.lang.annotation.RetentionPolicy;
/**
* MyBearingTracking exposes different types bearing tracking modes.
*
* @see MapView#setMyBearingTrackingMode(int)
* @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyBearingTrackingMode(int)
* @see MyLocationView#setMyBearingTrackingMode(int)
*/
public class MyBearingTracking {
/**
* Indicates the parameter accepts one of the values from {@link MyBearingTracking}.
*/
@IntDef({NONE, COMPASS, GPS, /**COMBINED**/})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Indicates the parameter accepts one of the values from {@link MyBearingTracking}.
*/
@IntDef( {NONE, COMPASS, GPS, /**COMBINED**/})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Bearing tracking is disabled
*/
public static final int NONE = 0x00000000;
/**
* 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 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
*/
public static final int GPS = 0x00000008;
//public static final int COMBINED = 0x00000012;
//public static final int COMBINED = 0x00000012;
}

View File

@@ -11,27 +11,27 @@ import java.lang.annotation.RetentionPolicy;
/**
* MyLocationTracking exposes different types of locational tracking modes.
*
* @see MapView#setMyLocationTrackingMode(int)
* @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyLocationTrackingMode(int)
* @see MyLocationView#setMyLocationTrackingMode(int)
*/
public class MyLocationTracking {
/**
* Indicates the parameter accepts one of the values from {@link MyLocationTracking}.
*/
@IntDef({TRACKING_NONE, TRACKING_FOLLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Indicates the parameter accepts one of the values from {@link MyLocationTracking}.
*/
@IntDef( {TRACKING_NONE, TRACKING_FOLLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Location tracking is disabled.
*/
public static final int TRACKING_NONE = 0x00000000;
/**
* Location tracking 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;
/**
* Tracking the location of the user, {@link MapView} will reposition to center of {@link MyLocationView}
*/
public static final int TRACKING_FOLLOW = 0x00000004;
}

View File

@@ -18,61 +18,61 @@ import java.lang.annotation.RetentionPolicy;
public class Style {
/**
* Indicates the parameter accepts one of the values from {@link Style}. Using one of these
* constants means your map style will always use the latest version and may change as we
* improve the style
*/
@StringDef({MAPBOX_STREETS, OUTDOORS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
@Retention(RetentionPolicy.SOURCE)
public @interface StyleUrl {
}
/**
* Indicates the parameter accepts one of the values from {@link Style}. Using one of these
* constants means your map style will always use the latest version and may change as we
* improve the style
*/
@StringDef( {MAPBOX_STREETS, OUTDOORS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
@Retention(RetentionPolicy.SOURCE)
public @interface StyleUrl {
}
// IMPORTANT: If you change any of these you also need to edit them in strings.xml
// IMPORTANT: If you change any of these you also need to edit them in strings.xml
/**
* Mapbox Streets: A complete basemap, perfect for incorporating your own data. Using this
* constant means your map style will always use the latest version and may change as we
* improve the style.
*/
public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9";
/**
* Mapbox Streets: A complete basemap, perfect for incorporating your own data. Using this
* constant means your map style will always use the latest version and may change as we
* improve the style.
*/
public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9";
/**
* Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means
* your map style will always use the latest version and may change as we improve the style.
*/
public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9";
/**
* Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means
* your map style will always use the latest version and may change as we improve the style.
*/
public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9";
/**
* Emerald: A versatile style, with emphasis on road networks and public transit.
*
* @deprecated this style has been deprecated and will be removed in future versions.
*/
@Deprecated
public static final String EMERALD = "mapbox://styles/mapbox/emerald-v8";
/**
* Emerald: A versatile style, with emphasis on road networks and public transit.
*
* @deprecated this style has been deprecated and will be removed in future versions.
*/
@Deprecated
public static final String EMERALD = "mapbox://styles/mapbox/emerald-v8";
/**
* Light: Subtle light backdrop for data visualizations. Using this constant means your map
* style will always use the latest version and may change as we improve the style.
*/
public static final String LIGHT = "mapbox://styles/mapbox/light-v9";
/**
* Light: Subtle light backdrop for data visualizations. Using this constant means your map
* style will always use the latest version and may change as we improve the style.
*/
public static final String LIGHT = "mapbox://styles/mapbox/light-v9";
/**
* Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style
* will always use the latest version and may change as we improve the style.
*/
public static final String DARK = "mapbox://styles/mapbox/dark-v9";
/**
* Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style
* will always use the latest version and may change as we improve the style.
*/
public static final String DARK = "mapbox://styles/mapbox/dark-v9";
/**
* Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means
* your map style will always use the latest version and may change as we improve the style.
*/
public static final String SATELLITE = "mapbox://styles/mapbox/satellite-v9";
/**
* Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means
* your map style will always use the latest version and may change as we improve the style.
*/
public static final String SATELLITE = "mapbox://styles/mapbox/satellite-v9";
/**
* Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this
* constant means your map style will always use the latest version and may change as we
* improve the style.
*/
public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9";
/**
* Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this
* constant means your map style will always use the latest version and may change as we
* improve the style.
*/
public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9";
}

View File

@@ -5,18 +5,18 @@ package com.mapbox.mapboxsdk.exceptions;
*/
public class ConversionException extends RuntimeException {
public ConversionException() {
}
public ConversionException() {
}
public ConversionException(String detailMessage) {
super(detailMessage);
}
public ConversionException(String detailMessage) {
super(detailMessage);
}
public ConversionException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
public ConversionException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
public ConversionException(Throwable throwable) {
super(throwable);
}
public ConversionException(Throwable throwable) {
super(throwable);
}
}

View File

@@ -19,9 +19,9 @@ import com.mapbox.mapboxsdk.maps.MapView;
*/
public class IconBitmapChangedException extends RuntimeException {
public IconBitmapChangedException() {
super("The added Marker has an Icon with a bitmap that has been modified. An Icon cannot be modified" +
"after it has been added to the map in a Marker.");
}
public IconBitmapChangedException() {
super("The added Marker has an Icon with a bitmap that has been modified. An Icon cannot be modified"
+ "after it has been added to the map in a Marker.");
}
}

View File

@@ -5,18 +5,19 @@ import android.os.Bundle;
import com.mapbox.mapboxsdk.maps.MapView;
/**
* A {@code InvalidAccessTokenException} is thrown by {@link com.mapbox.mapboxsdk.maps.MapboxMap} when there is either no access
* token set before {@link MapView#onCreate(Bundle)} or an invalid access token is set in {@link MapView#setAccessToken(String)}
* A {@code InvalidAccessTokenException} is thrown by {@link com.mapbox.mapboxsdk.maps.MapboxMap} when there is either
* no access token set before {@link MapView#onCreate(Bundle)} or an invalid access token is set in
* {@link MapView#setAccessToken(String)}
*
* @see MapView#onCreate(Bundle)
* @see MapView#setAccessToken(String)
*/
public class InvalidAccessTokenException extends RuntimeException {
public InvalidAccessTokenException() {
super("\nUsing MapView requires setting a valid access token. Use setAccessToken on Mapview to provide one. " +
"\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one." +
"\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
}
public InvalidAccessTokenException() {
super("\nUsing MapView requires setting a valid access token. Use setAccessToken on Mapview to provide one. "
+ "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one."
+ "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
}
}

View File

@@ -6,7 +6,7 @@ package com.mapbox.mapboxsdk.exceptions;
*/
public class InvalidLatLngBoundsException extends RuntimeException {
public InvalidLatLngBoundsException(int latLngsListSize) {
super("Cannot create a LatLngBounds from " + latLngsListSize + " items");
}
public InvalidLatLngBoundsException(int latLngsListSize) {
super("Cannot create a LatLngBounds from " + latLngsListSize + " items");
}
}

View File

@@ -2,9 +2,9 @@ package com.mapbox.mapboxsdk.exceptions;
public class InvalidMarkerPositionException extends RuntimeException {
public InvalidMarkerPositionException() {
super("Adding an invalid Marker to a Map. " +
"Missing the required position field. " +
"Provide a non null LatLng as position to the Marker.");
}
public InvalidMarkerPositionException() {
super("Adding an invalid Marker to a Map. "
+ "Missing the required position field. "
+ "Provide a non null LatLng as position to the Marker.");
}
}

View File

@@ -1,7 +1,5 @@
package com.mapbox.mapboxsdk.exceptions;
import android.content.Context;
import android.os.Bundle;
import com.mapbox.mapboxsdk.MapboxAccountManager;
@@ -12,12 +10,13 @@ import com.mapbox.mapboxsdk.maps.MapView;
* when {@link MapboxAccountManager} is not started before {@link MapView#onCreate(Bundle)}.
*
* @see MapView#onCreate(Bundle)
* @see MapboxAccountManager#start(Context, String)
* @see MapboxAccountManager#start(android.content.Context, String)
*/
public class MapboxAccountManagerNotStartedException extends RuntimeException {
public MapboxAccountManagerNotStartedException() {
super("\nMapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. " +
"\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
}
public MapboxAccountManagerNotStartedException() {
super("\nMapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to"
+ "initialise. "
+ "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
}
}

View File

@@ -12,10 +12,11 @@ import com.mapbox.mapboxsdk.maps.MapView;
*/
public class TelemetryServiceNotConfiguredException extends RuntimeException {
public TelemetryServiceNotConfiguredException() {
super("\nTelemetryService is not configured in your applications AndroidManifest.xml. " +
"\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications AndroidManifest.xml" +
"\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/.");
}
public TelemetryServiceNotConfiguredException() {
super("\nTelemetryService is not configured in your applications AndroidManifest.xml. "
+ "\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications "
+ "AndroidManifest.xml"
+ "\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/.");
}
}

View File

@@ -14,8 +14,8 @@ import com.mapbox.mapboxsdk.annotations.IconFactory;
*/
public class TooManyIconsException extends RuntimeException {
public TooManyIconsException() {
super("Cannot create an Icon because there are already too many. Try reusing Icon objects whenever possible.");
}
public TooManyIconsException() {
super("Cannot create an Icon because there are already too many. Try reusing Icon objects whenever possible.");
}
}

View File

@@ -4,9 +4,9 @@ package com.mapbox.mapboxsdk.geometry;
* Describes a latitude, longitude point.
*/
public interface ILatLng {
double getLatitude();
double getLatitude();
double getLongitude();
double getLongitude();
double getAltitude();
double getAltitude();
}

View File

@@ -4,7 +4,7 @@ package com.mapbox.mapboxsdk.geometry;
* Describes a projection in Mercator meters.
*/
public interface IProjectedMeters {
double getNorthing();
double getNorthing();
double getEasting();
double getEasting();
}

View File

@@ -21,183 +21,191 @@ import com.mapbox.mapboxsdk.utils.MathUtils;
*/
public class LatLng implements ILatLng, Parcelable {
public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
public LatLng createFromParcel(Parcel in) {
return new LatLng(in);
}
public LatLng[] newArray(int size) {
return new LatLng[size];
}
};
private double latitude;
private double longitude;
private double altitude = 0.0;
/**
* Construct a new latitude, longitude point at (0, 0)
*/
public LatLng() {
this.latitude = 0.0;
this.longitude = 0.0;
public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
public LatLng createFromParcel(Parcel in) {
return new LatLng(in);
}
/**
* Construct a new latitude, longitude point given float arguments
* @param latitude Latitude in degrees
* @param longitude Longitude in degrees
*/
public LatLng(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
public LatLng[] newArray(int size) {
return new LatLng[size];
}
};
private double latitude;
private double longitude;
private double altitude = 0.0;
/**
* Construct a new latitude, longitude point at (0, 0)
*/
public LatLng() {
this.latitude = 0.0;
this.longitude = 0.0;
}
/**
* Construct a new latitude, longitude point given float arguments
*
* @param latitude Latitude in degrees
* @param longitude Longitude in degrees
*/
public LatLng(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
/**
* Construct a new latitude, longitude, altitude point given float arguments
*
* @param latitude Latitude in degrees
* @param longitude Longitude in degress
* @param altitude Altitude in meters
*/
public LatLng(double latitude, double longitude, double altitude) {
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
}
/**
* Transform a Location into a LatLng point
*
* @param location Android Location
*/
public LatLng(Location location) {
this(location.getLatitude(), location.getLongitude(), location.getAltitude());
}
/**
* Clone an existing latitude longitude point
*
* @param aLatLng LatLng
*/
public LatLng(LatLng aLatLng) {
this.latitude = aLatLng.latitude;
this.longitude = aLatLng.longitude;
this.altitude = aLatLng.altitude;
}
protected LatLng(Parcel in) {
latitude = in.readDouble();
longitude = in.readDouble();
altitude = in.readDouble();
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
@Override
public double getLatitude() {
return latitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
@Override
public double getLongitude() {
return longitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
@Override
public double getAltitude() {
return altitude;
}
/**
* Return a new LatLng object with a wrapped Longitude. This allows original data object
* to remain unchanged.
*
* @return New LatLng object with wrapped Longitude
*/
public LatLng wrap() {
LatLng wrappedVersion = new LatLng(this);
double lon = wrappedVersion.getLongitude();
if (lon < GeoConstants.MIN_LONGITUDE || lon > GeoConstants.MAX_LONGITUDE) {
wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE,
GeoConstants.MAX_LONGITUDE));
}
return wrappedVersion;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
/**
* Construct a new latitude, longitude, altitude point given float arguments
* @param latitude Latitude in degrees
* @param longitude Longitude in degress
* @param altitude Altitude in meters
*/
public LatLng(double latitude, double longitude, double altitude) {
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
LatLng latLng = (LatLng) object;
return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0
&& Double.compare(latLng.longitude, longitude) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(latitude);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(longitude);
result = 31 * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(altitude);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public String toString() {
return "LatLng [latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(latitude);
out.writeDouble(longitude);
out.writeDouble(altitude);
}
/**
* Calculate distance between two points
*
* @param other Other LatLng to compare to
* @return distance in meters
*/
public double distanceTo(LatLng other) {
if (latitude == other.latitude && longitude == other.longitude) {
// return 0.0 to avoid a NaN
return 0.0;
}
/**
* Transform a Location into a LatLng point
* @param location Android Location
*/
public LatLng(Location location) {
this(location.getLatitude(), location.getLongitude(), location.getAltitude());
}
final double a1 = Math.toRadians(this.latitude);
final double a2 = Math.toRadians(this.longitude);
final double b1 = Math.toRadians(other.getLatitude());
final double b2 = Math.toRadians(other.getLongitude());
/**
* Clone an existing latitude longitude point
* @param aLatLng LatLng
*/
public LatLng(LatLng aLatLng) {
this.latitude = aLatLng.latitude;
this.longitude = aLatLng.longitude;
this.altitude = aLatLng.altitude;
}
final double cosa1 = Math.cos(a1);
final double cosb1 = Math.cos(b1);
protected LatLng(Parcel in) {
latitude = in.readDouble();
longitude = in.readDouble();
altitude = in.readDouble();
}
final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
final double t3 = Math.sin(a1) * Math.sin(b1);
final double tt = Math.acos(t1 + t2 + t3);
public void setLatitude(double latitude) {
this.latitude = latitude;
}
@Override
public double getLatitude() {
return latitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
@Override
public double getLongitude() {
return longitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
@Override
public double getAltitude() {
return altitude;
}
/**
* Return a new LatLng object with a wrapped Longitude. This allows original data object
* to remain unchanged.
* @return New LatLng object with wrapped Longitude
*/
public LatLng wrap(){
LatLng wrappedVersion = new LatLng(this);
double lon = wrappedVersion.getLongitude();
if (lon < GeoConstants.MIN_LONGITUDE || lon > GeoConstants.MAX_LONGITUDE) {
wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE));
}
return wrappedVersion;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LatLng latLng = (LatLng) o;
return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0 && Double.compare(latLng.longitude, longitude) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(latitude);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(longitude);
result = 31 * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(altitude);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public String toString() {
return "LatLng [latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(latitude);
out.writeDouble(longitude);
out.writeDouble(altitude);
}
/**
* Calculate distance between two points
* @param other Other LatLng to compare to
* @return distance in meters
*/
public double distanceTo(LatLng other) {
if(latitude == other.latitude && longitude == other.longitude){
// return 0.0 to avoid a NaN
return 0.0;
}
final double a1 = Math.toRadians(this.latitude);
final double a2 = Math.toRadians(this.longitude);
final double b1 = Math.toRadians(other.getLatitude());
final double b2 = Math.toRadians(other.getLongitude());
final double cosa1 = Math.cos(a1);
final double cosb1 = Math.cos(b1);
final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
final double t3 = Math.sin(a1) * Math.sin(b1);
final double tt = Math.acos(t1 + t2 + t3);
return GeoConstants.RADIUS_EARTH_METERS * tt;
}
return GeoConstants.RADIUS_EARTH_METERS * tt;
}
}

View File

@@ -14,292 +14,296 @@ import java.util.List;
*/
public class LatLngBounds implements Parcelable {
private final double mLatNorth;
private final double mLatSouth;
private final double mLonEast;
private final double mLonWest;
private final double mLatNorth;
private final double mLatSouth;
private final double mLonEast;
private final double mLonWest;
/**
* Construct a new LatLngBounds based on its corners, given in NESW
* order.
*
* @param northLatitude Northern Latitude
* @param eastLongitude Eastern Longitude
* @param southLatitude Southern Latitude
* @param westLongitude Western Longitude
*/
LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude, final double westLongitude) {
this.mLatNorth = northLatitude;
this.mLonEast = eastLongitude;
this.mLatSouth = southLatitude;
this.mLonWest = westLongitude;
/**
* Construct a new LatLngBounds based on its corners, given in NESW
* order.
*
* @param northLatitude Northern Latitude
* @param eastLongitude Eastern Longitude
* @param southLatitude Southern Latitude
* @param westLongitude Western Longitude
*/
LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude,
final double westLongitude) {
this.mLatNorth = northLatitude;
this.mLonEast = eastLongitude;
this.mLatSouth = southLatitude;
this.mLonWest = westLongitude;
}
/**
* Calculates the centerpoint of this LatLngBounds by simple interpolation and returns
* it as a point. This is a non-geodesic calculation which is not the geographic center.
*
* @return LatLng center of this LatLngBounds
*/
public LatLng getCenter() {
return new LatLng((this.mLatNorth + this.mLatSouth) / 2,
(this.mLonEast + this.mLonWest) / 2);
}
public double getLatNorth() {
return this.mLatNorth;
}
public double getLatSouth() {
return this.mLatSouth;
}
public double getLonEast() {
return this.mLonEast;
}
public double getLonWest() {
return this.mLonWest;
}
/**
* Get the area spanned by this LatLngBounds
*
* @return LatLngSpan area
*/
public LatLngSpan getSpan() {
return new LatLngSpan(getLatitudeSpan(), getLongitudeSpan());
}
/**
* Get the absolute distance, in degrees, between the north and
* south boundaries of this LatLngBounds
*
* @return Span distance
*/
public double getLatitudeSpan() {
return Math.abs(this.mLatNorth - this.mLatSouth);
}
/**
* Get the absolute distance, in degrees, between the west and
* east boundaries of this LatLngBounds
*
* @return Span distance
*/
public double getLongitudeSpan() {
return Math.abs(this.mLonEast - this.mLonWest);
}
/**
* Validate if LatLngBounds is empty, determined if absolute distance is
*
* @return boolean indicating if span is empty
*/
public boolean isEmptySpan() {
return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0;
}
@Override
public String toString() {
return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest;
}
/**
* Constructs a LatLngBounds that contains all of a list of LatLng
* objects. Empty lists will yield invalid LatLngBounds.
*
* @param latLngs List of LatLng objects
* @return LatLngBounds
*/
static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) {
double minLat = 90;
double minLon = 180;
double maxLat = -90;
double maxLon = -180;
for (final ILatLng gp : latLngs) {
final double latitude = gp.getLatitude();
final double longitude = gp.getLongitude();
minLat = Math.min(minLat, latitude);
minLon = Math.min(minLon, longitude);
maxLat = Math.max(maxLat, latitude);
maxLon = Math.max(maxLon, longitude);
}
/**
* Calculates the centerpoint of this LatLngBounds by simple interpolation and returns
* it as a point. This is a non-geodesic calculation which is not the geographic center.
*
* @return LatLng center of this LatLngBounds
*/
public LatLng getCenter() {
return new LatLng((this.mLatNorth + this.mLatSouth) / 2,
(this.mLonEast + this.mLonWest) / 2);
return new LatLngBounds(maxLat, maxLon, minLat, minLon);
}
public LatLng[] toLatLngs() {
return new LatLng[] {new LatLng(mLatNorth, mLonEast), new LatLng(mLatSouth, mLonWest)};
}
/**
* Determines whether this LatLngBounds matches another one via LatLng.
*
* @param o another object
* @return a boolean indicating whether the LatLngBounds are equal
*/
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o instanceof LatLngBounds) {
LatLngBounds other = (LatLngBounds) o;
return mLatNorth == other.getLatNorth()
&& mLatSouth == other.getLatSouth()
&& mLonEast == other.getLonEast()
&& mLonWest == other.getLonWest();
}
return false;
}
/**
* Determines whether this LatLngBounds contains a point and the point
* does not touch its boundary.
*
* @param latLng the point which may be contained
* @return true, if the point is contained within the box.
*/
public boolean contains(final ILatLng latLng) {
final double latitude = latLng.getLatitude();
final double longitude = latLng.getLongitude();
return ((latitude < this.mLatNorth)
&& (latitude > this.mLatSouth))
&& ((longitude < this.mLonEast)
&& (longitude > this.mLonWest));
}
/**
* Returns a new LatLngBounds that stretches to contain both this and another LatLngBounds.
*
* @param bounds LatLngBounds to add
* @return LatLngBounds
*/
public LatLngBounds union(LatLngBounds bounds) {
return union(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest());
}
/**
* Returns a new LatLngBounds that stretches to include another LatLngBounds,
* given by corner points.
*
* @param lonNorth Northern Longitude
* @param latEast Eastern Latitude
* @param lonSouth Southern Longitude
* @param latWest Western Longitude
* @return BoundingBox
*/
public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) {
return new LatLngBounds((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth,
(this.mLonEast < latEast) ? latEast : this.mLonEast,
(this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth,
(this.mLonWest > latWest) ? latWest : this.mLonWest);
}
/**
* Returns a new LatLngBounds that is the intersection of this with another box
*
* @param box LatLngBounds to intersect with
* @return LatLngBounds
*/
public LatLngBounds intersect(LatLngBounds box) {
double minLatWest = Math.max(getLonWest(), box.getLonWest());
double maxLatEast = Math.min(getLonEast(), box.getLonEast());
if (maxLatEast > minLatWest) {
double minLonSouth = Math.max(getLatSouth(), box.getLatSouth());
double maxLonNorth = Math.min(getLatNorth(), box.getLatNorth());
if (maxLonNorth > minLonSouth) {
return new LatLngBounds(maxLonNorth, maxLatEast, minLonSouth, minLatWest);
}
}
return null;
}
/**
* Returns a new LatLngBounds that is the intersection of this with another LatLngBounds
*
* @param northLatitude Northern Longitude
* @param eastLongitude Eastern Latitude
* @param southLatitude Southern Longitude
* @param westLongitude Western Latitude
* @return LatLngBounds
*/
public LatLngBounds intersect(double northLatitude, double eastLongitude, double southLatitude,
double westLongitude) {
return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude));
}
public static final Parcelable.Creator<LatLngBounds> CREATOR =
new Parcelable.Creator<LatLngBounds>() {
@Override
public LatLngBounds createFromParcel(final Parcel in) {
return readFromParcel(in);
}
@Override
public LatLngBounds[] newArray(final int size) {
return new LatLngBounds[size];
}
};
@Override
public int hashCode() {
return (int) ((mLatNorth + 90)
+ ((mLatSouth + 90) * 1000)
+ ((mLonEast + 180) * 1000000)
+ ((mLonEast + 180) * 1000000000));
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel out, final int arg1) {
out.writeDouble(this.mLatNorth);
out.writeDouble(this.mLonEast);
out.writeDouble(this.mLatSouth);
out.writeDouble(this.mLonWest);
}
private static LatLngBounds readFromParcel(final Parcel in) {
final double lonNorth = in.readDouble();
final double latEast = in.readDouble();
final double lonSouth = in.readDouble();
final double latWest = in.readDouble();
return new LatLngBounds(lonNorth, latEast, lonSouth, latWest);
}
/**
* Builder for composing LatLngBounds objects.
*/
public static final class Builder {
private List<LatLng> mLatLngList;
public Builder() {
mLatLngList = new ArrayList<>();
}
public double getLatNorth() {
return this.mLatNorth;
public LatLngBounds build() {
if (mLatLngList.size() < 2) {
throw new InvalidLatLngBoundsException(mLatLngList.size());
}
return LatLngBounds.fromLatLngs(mLatLngList);
}
public double getLatSouth() {
return this.mLatSouth;
public Builder includes(List<LatLng> latLngs) {
for (LatLng point : latLngs) {
mLatLngList.add(point);
}
return this;
}
public double getLonEast() {
return this.mLonEast;
}
public double getLonWest() {
return this.mLonWest;
}
/**
* Get the area spanned by this LatLngBounds
*
* @return LatLngSpan area
*/
public LatLngSpan getSpan() {
return new LatLngSpan(getLatitudeSpan(), getLongitudeSpan());
}
/**
* Get the absolute distance, in degrees, between the north and
* south boundaries of this LatLngBounds
*
* @return Span distance
*/
public double getLatitudeSpan() {
return Math.abs(this.mLatNorth - this.mLatSouth);
}
/**
* Get the absolute distance, in degrees, between the west and
* east boundaries of this LatLngBounds
*
* @return Span distance
*/
public double getLongitudeSpan() {
return Math.abs(this.mLonEast - this.mLonWest);
}
/**
* Validate if LatLngBounds is empty, determined if absolute distance is
*
* @return boolean indicating if span is empty
*/
public boolean isEmptySpan() {
return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0;
}
@Override
public String toString() {
return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest;
}
/**
* Constructs a LatLngBounds that contains all of a list of LatLng
* objects. Empty lists will yield invalid LatLngBounds.
*
* @param latLngs List of LatLng objects
* @return LatLngBounds
*/
static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) {
double minLat = 90,
minLon = 180,
maxLat = -90,
maxLon = -180;
for (final ILatLng gp : latLngs) {
final double latitude = gp.getLatitude();
final double longitude = gp.getLongitude();
minLat = Math.min(minLat, latitude);
minLon = Math.min(minLon, longitude);
maxLat = Math.max(maxLat, latitude);
maxLon = Math.max(maxLon, longitude);
}
return new LatLngBounds(maxLat, maxLon, minLat, minLon);
}
public LatLng[] toLatLngs() {
return new LatLng[]{new LatLng(mLatNorth, mLonEast), new LatLng(mLatSouth, mLonWest)};
}
/**
* Determines whether this LatLngBounds matches another one via LatLng.
*
* @param o another object
* @return a boolean indicating whether the LatLngBounds are equal
*/
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o instanceof LatLngBounds) {
LatLngBounds other = (LatLngBounds) o;
return mLatNorth == other.getLatNorth()
&& mLatSouth == other.getLatSouth()
&& mLonEast == other.getLonEast()
&& mLonWest == other.getLonWest();
}
return false;
}
/**
* Determines whether this LatLngBounds contains a point and the point
* does not touch its boundary.
*
* @param latLng the point which may be contained
* @return true, if the point is contained within the box.
*/
public boolean contains(final ILatLng latLng) {
final double latitude = latLng.getLatitude();
final double longitude = latLng.getLongitude();
return ((latitude < this.mLatNorth)
&& (latitude > this.mLatSouth))
&& ((longitude < this.mLonEast)
&& (longitude > this.mLonWest));
}
/**
* Returns a new LatLngBounds that stretches to contain both this and another LatLngBounds.
*
* @param bounds LatLngBounds to add
* @return LatLngBounds
*/
public LatLngBounds union(LatLngBounds bounds) {
return union(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest());
}
/**
* Returns a new LatLngBounds that stretches to include another LatLngBounds,
* given by corner points.
*
* @param lonNorth Northern Longitude
* @param latEast Eastern Latitude
* @param lonSouth Southern Longitude
* @param latWest Western Longitude
* @return BoundingBox
*/
public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) {
return new LatLngBounds((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth,
(this.mLonEast < latEast) ? latEast : this.mLonEast,
(this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth,
(this.mLonWest > latWest) ? latWest : this.mLonWest);
}
/**
* Returns a new LatLngBounds that is the intersection of this with another box
*
* @param box LatLngBounds to intersect with
* @return LatLngBounds
*/
public LatLngBounds intersect(LatLngBounds box) {
double minLatWest = Math.max(getLonWest(), box.getLonWest());
double maxLatEast = Math.min(getLonEast(), box.getLonEast());
if (maxLatEast > minLatWest) {
double minLonSouth = Math.max(getLatSouth(), box.getLatSouth());
double maxLonNorth = Math.min(getLatNorth(), box.getLatNorth());
if (maxLonNorth > minLonSouth) {
return new LatLngBounds(maxLonNorth, maxLatEast, minLonSouth, minLatWest);
}
}
return null;
}
/**
* Returns a new LatLngBounds that is the intersection of this with another LatLngBounds
*
* @param northLatitude Northern Longitude
* @param eastLongitude Eastern Latitude
* @param southLatitude Southern Longitude
* @param westLongitude Western Latitude
* @return LatLngBounds
*/
public LatLngBounds intersect(double northLatitude, double eastLongitude, double southLatitude, double westLongitude) {
return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude));
}
public static final Parcelable.Creator<LatLngBounds> CREATOR =
new Parcelable.Creator<LatLngBounds>() {
@Override
public LatLngBounds createFromParcel(final Parcel in) {
return readFromParcel(in);
}
@Override
public LatLngBounds[] newArray(final int size) {
return new LatLngBounds[size];
}
};
@Override
public int hashCode() {
return (int) ((mLatNorth + 90)
+ ((mLatSouth + 90) * 1000)
+ ((mLonEast + 180) * 1000000)
+ ((mLonEast + 180) * 1000000000));
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel out, final int arg1) {
out.writeDouble(this.mLatNorth);
out.writeDouble(this.mLonEast);
out.writeDouble(this.mLatSouth);
out.writeDouble(this.mLonWest);
}
private static LatLngBounds readFromParcel(final Parcel in) {
final double lonNorth = in.readDouble();
final double latEast = in.readDouble();
final double lonSouth = in.readDouble();
final double latWest = in.readDouble();
return new LatLngBounds(lonNorth, latEast, lonSouth, latWest);
}
/**
* Builder for composing LatLngBounds objects.
*/
public static final class Builder {
private List<LatLng> mLatLngList;
public Builder() {
mLatLngList = new ArrayList<>();
}
public LatLngBounds build() {
if (mLatLngList.size() < 2) {
throw new InvalidLatLngBoundsException(mLatLngList.size());
}
return LatLngBounds.fromLatLngs(mLatLngList);
}
public Builder includes(List<LatLng> latLngs){
for (LatLng point : latLngs) {
mLatLngList.add(point);
}
return this;
}
public Builder include(@NonNull LatLng latLng) {
mLatLngList.add(latLng);
return this;
}
public Builder include(@NonNull LatLng latLng) {
mLatLngList.add(latLng);
return this;
}
}
}

View File

@@ -9,93 +9,95 @@ import android.support.annotation.NonNull;
*/
public class LatLngSpan implements Parcelable {
private double mLatitudeSpan;
private double mLongitudeSpan;
private double mLatitudeSpan;
private double mLongitudeSpan;
private LatLngSpan(@NonNull Parcel in) {
mLatitudeSpan = in.readDouble();
mLongitudeSpan = in.readDouble();
private LatLngSpan(@NonNull Parcel in) {
mLatitudeSpan = in.readDouble();
mLongitudeSpan = in.readDouble();
}
/**
* Creates a LatLgnSpan.
*
* @param latitudeSpan The span used for latitude.
* @param longitudeSpan The span used for longitude.
*/
public LatLngSpan(double latitudeSpan, double longitudeSpan) {
mLatitudeSpan = latitudeSpan;
mLongitudeSpan = longitudeSpan;
}
/**
* Returns the latitude span.
*
* @return The latitude span.
*/
public double getLatitudeSpan() {
return mLatitudeSpan;
}
/**
* Sets the latitude span.
*
* @param latitudeSpan The latitude span to set.
*/
public void setLatitudeSpan(double latitudeSpan) {
mLatitudeSpan = latitudeSpan;
}
/**
* Returns to longitude span.
*
* @return The longitude span.
*/
public double getLongitudeSpan() {
return mLongitudeSpan;
}
/**
* Sets the longitude span.
*
* @param longitudeSpan The longitude span to set.
*/
public void setLongitudeSpan(double longitudeSpan) {
mLongitudeSpan = longitudeSpan;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
/**
* Creates a LatLgnSpan.
*
* @param latitudeSpan The span used for latitude.
* @param longitudeSpan The span used for longitude.
*/
public LatLngSpan(double latitudeSpan, double longitudeSpan) {
mLatitudeSpan = latitudeSpan;
mLongitudeSpan = longitudeSpan;
if (o instanceof LatLngSpan) {
LatLngSpan other = (LatLngSpan) o;
return mLongitudeSpan == other.getLongitudeSpan()
&& mLatitudeSpan == other.getLatitudeSpan();
}
return false;
}
/**
* Returns the latitude span.
*
* @return The latitude span.
*/
public double getLatitudeSpan() {
return mLatitudeSpan;
}
public static final Parcelable.Creator<LatLngSpan> CREATOR =
new Parcelable.Creator<LatLngSpan>() {
@Override
public LatLngSpan createFromParcel(Parcel in) {
return new LatLngSpan(in);
}
/**
* Sets the latitude span.
*
* @param latitudeSpan The latitude span to set.
*/
public void setLatitudeSpan(double latitudeSpan) {
mLatitudeSpan = latitudeSpan;
}
@Override
public LatLngSpan[] newArray(int size) {
return new LatLngSpan[size];
}
};
/**
* Returns to longitude span.
*
* @return The longitude span.
*/
public double getLongitudeSpan() {
return mLongitudeSpan;
}
@Override
public int describeContents() {
return 0;
}
/**
* Sets the longitude span.
*
* @param longitudeSpan The longitude span to set.
*/
public void setLongitudeSpan(double longitudeSpan) {
mLongitudeSpan = longitudeSpan;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof LatLngSpan) {
LatLngSpan other = (LatLngSpan) o;
return mLongitudeSpan == other.getLongitudeSpan()
&& mLatitudeSpan == other.getLatitudeSpan();
}
return false;
}
public static final Parcelable.Creator<LatLngSpan> CREATOR =
new Parcelable.Creator<LatLngSpan>() {
@Override
public LatLngSpan createFromParcel(Parcel in) {
return new LatLngSpan(in);
}
@Override
public LatLngSpan[] newArray(int size) {
return new LatLngSpan[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int arg1) {
out.writeDouble(mLatitudeSpan);
out.writeDouble(mLongitudeSpan);
}
@Override
public void writeToParcel(Parcel out, int arg1) {
out.writeDouble(mLatitudeSpan);
out.writeDouble(mLongitudeSpan);
}
}

View File

@@ -13,104 +13,105 @@ import android.os.Parcelable;
*/
public class ProjectedMeters implements IProjectedMeters, Parcelable {
public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
public ProjectedMeters createFromParcel(Parcel in) {
return new ProjectedMeters(in);
}
public ProjectedMeters[] newArray(int size) {
return new ProjectedMeters[size];
}
};
private double northing;
private double easting;
/**
* Creates a ProjectedMeters based on projected meters in north and east direction.
*
* @param northing the northing in meters
* @param easting the easting in meters
*/
public ProjectedMeters(double northing, double easting) {
this.northing = northing;
this.easting = easting;
public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
public ProjectedMeters createFromParcel(Parcel in) {
return new ProjectedMeters(in);
}
/**
* Creates a ProjecteMeters based on another set of projected meters.
*
* @param projectedMeters The projected meters to be based on.
*/
public ProjectedMeters(ProjectedMeters projectedMeters) {
this.northing = projectedMeters.northing;
this.easting = projectedMeters.easting;
public ProjectedMeters[] newArray(int size) {
return new ProjectedMeters[size];
}
};
private double northing;
private double easting;
/**
* Creates a ProjectedMeters based on projected meters in north and east direction.
*
* @param northing the northing in meters
* @param easting the easting in meters
*/
public ProjectedMeters(double northing, double easting) {
this.northing = northing;
this.easting = easting;
}
/**
* Creates a ProjecteMeters based on another set of projected meters.
*
* @param projectedMeters The projected meters to be based on.
*/
public ProjectedMeters(ProjectedMeters projectedMeters) {
this.northing = projectedMeters.northing;
this.easting = projectedMeters.easting;
}
private ProjectedMeters(Parcel in) {
northing = in.readDouble();
easting = in.readDouble();
}
/**
* Get projected meters in north direction.
*
* @return Projected meters in north.
*/
@Override
public double getNorthing() {
return northing;
}
/**
* Get projected meters in east direction.
*
* @return Projected meters in east.
*/
@Override
public double getEasting() {
return easting;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
private ProjectedMeters(Parcel in) {
northing = in.readDouble();
easting = in.readDouble();
}
ProjectedMeters projectedMeters = (ProjectedMeters) o;
/**
* Get projected meters in north direction.
*
* @return Projected meters in north.
*/
@Override
public double getNorthing() {
return northing;
}
return Double.compare(projectedMeters.easting, easting) == 0
&& Double.compare(projectedMeters.northing, northing) == 0;
/**
* Get projected meters in east direction.
*
* @return Projected meters in east.
*/
@Override
public double getEasting() {
return easting;
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(easting);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(northing);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
ProjectedMeters projectedMeters = (ProjectedMeters) o;
@Override
public String toString() {
return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]";
}
return Double.compare(projectedMeters.easting, easting) == 0 && Double.compare(projectedMeters.northing, northing) == 0;
@Override
public int describeContents() {
return 0;
}
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(easting);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(northing);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public String toString() {
return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(northing);
out.writeDouble(easting);
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(northing);
out.writeDouble(easting);
}
}

View File

@@ -12,118 +12,119 @@ import android.os.Parcelable;
*/
public class VisibleRegion implements Parcelable {
/**
* LatLng object that defines the far left corner of the camera.
*/
public final LatLng farLeft;
/**
* LatLng object that defines the far left corner of the camera.
*/
public final LatLng farLeft;
/**
* LatLng object that defines the far right corner of the camera.
*/
public final LatLng farRight;
/**
* LatLng object that defines the far right corner of the camera.
*/
public final LatLng farRight;
/**
* LatLng object that defines the bottom left corner of the camera.
*/
public final LatLng nearLeft;
/**
* LatLng object that defines the bottom left corner of the camera.
*/
public final LatLng nearLeft;
/**
* LatLng object that defines the bottom right corner of the camera.
*/
public final LatLng nearRight;
/**
* LatLng object that defines the bottom right corner of the camera.
*/
public final LatLng nearRight;
/**
* The smallest bounding box that includes the visible region defined in this class.
*/
public final LatLngBounds latLngBounds;
/**
* The smallest bounding box that includes the visible region defined in this class.
*/
public final LatLngBounds latLngBounds;
private VisibleRegion(Parcel in) {
this.farLeft = in.readParcelable(LatLng.class.getClassLoader());
this.farRight = in.readParcelable(LatLng.class.getClassLoader());
this.nearLeft = in.readParcelable(LatLng.class.getClassLoader());
this.nearRight = in.readParcelable(LatLng.class.getClassLoader());
this.latLngBounds = in.readParcelable(LatLngBounds.class.getClassLoader());
private VisibleRegion(Parcel in) {
this.farLeft = in.readParcelable(LatLng.class.getClassLoader());
this.farRight = in.readParcelable(LatLng.class.getClassLoader());
this.nearLeft = in.readParcelable(LatLng.class.getClassLoader());
this.nearRight = in.readParcelable(LatLng.class.getClassLoader());
this.latLngBounds = in.readParcelable(LatLngBounds.class.getClassLoader());
}
/**
* Creates a new VisibleRegion given the four corners of the camera.
*
* @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param nearLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param nearRight A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param latLngBounds The smallest bounding box that includes the visible region defined in this class.
*/
public VisibleRegion(LatLng farLeft, LatLng farRight, LatLng nearLeft, LatLng nearRight, LatLngBounds latLngBounds) {
this.farLeft = farLeft;
this.farRight = farRight;
this.nearLeft = nearLeft;
this.nearRight = nearRight;
this.latLngBounds = latLngBounds;
}
/**
* Compares this VisibleRegion to another object.
* If the other object is actually a pointer to this object,
* or if all four corners and the bounds of the two objects are the same,
* this method returns true. Otherwise, this method returns false.
*
* @param o The Object to compare with.
* @return true if both objects are the same object.
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof VisibleRegion)) {
return false;
}
if (o == this) {
return true;
}
/**
* Creates a new VisibleRegion given the four corners of the camera.
*
* @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param nearLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param nearRight A LatLng object containing the latitude and longitude of the near left corner of the region.
* @param latLngBounds The smallest bounding box that includes the visible region defined in this class.
*/
public VisibleRegion(LatLng farLeft, LatLng farRight, LatLng nearLeft, LatLng nearRight, LatLngBounds latLngBounds) {
this.farLeft = farLeft;
this.farRight = farRight;
this.nearLeft = nearLeft;
this.nearRight = nearRight;
this.latLngBounds = latLngBounds;
}
VisibleRegion visibleRegion = (VisibleRegion) o;
return farLeft.equals(visibleRegion.farLeft)
&& farRight.equals(visibleRegion.farRight)
&& nearLeft.equals(visibleRegion.nearLeft)
&& nearRight.equals(visibleRegion.nearRight)
&& latLngBounds.equals(visibleRegion.latLngBounds);
}
/**
* Compares this VisibleRegion to another object.
* If the other object is actually a pointer to this object,
* or if all four corners and the bounds of the two objects are the same,
* this method returns true. Otherwise, this method returns false.
*
* @param o The Object to compare with.
* @return true if both objects are the same object.
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof VisibleRegion)) {
return false;
}
if (o == this) {
return true;
}
@Override
public String toString() {
return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight ["
+ nearRight + "], latLngBounds [" + latLngBounds + "]]";
}
VisibleRegion visibleRegion = (VisibleRegion) o;
return farLeft.equals(visibleRegion.farLeft)
&& farRight.equals(visibleRegion.farRight)
&& nearLeft.equals(visibleRegion.nearLeft)
&& nearRight.equals(visibleRegion.nearRight)
&& latLngBounds.equals(visibleRegion.latLngBounds);
}
@Override
public int hashCode() {
return ((farLeft.hashCode() + 90)
+ ((farRight.hashCode() + 90) * 1000)
+ ((nearLeft.hashCode() + 180) * 1000000)
+ ((nearRight.hashCode() + 180) * 1000000000));
}
@Override
public String toString() {
return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds [" + latLngBounds + "]]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public int hashCode() {
return ((farLeft.hashCode() + 90)
+ ((farRight.hashCode() + 90) * 1000)
+ ((nearLeft.hashCode() + 180) * 1000000)
+ ((nearRight.hashCode() + 180) * 1000000000));
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(farLeft, flags);
out.writeParcelable(farRight, flags);
out.writeParcelable(nearLeft, flags);
out.writeParcelable(nearRight, flags);
out.writeParcelable(latLngBounds, flags);
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<VisibleRegion> CREATOR =
new Parcelable.Creator<VisibleRegion>() {
public VisibleRegion createFromParcel(Parcel in) {
return new VisibleRegion(in);
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(farLeft, flags);
out.writeParcelable(farRight, flags);
out.writeParcelable(nearLeft, flags);
out.writeParcelable(nearRight, flags);
out.writeParcelable(latLngBounds, flags);
}
public static final Parcelable.Creator<VisibleRegion> CREATOR
= new Parcelable.Creator<VisibleRegion>() {
public VisibleRegion createFromParcel(Parcel in) {
return new VisibleRegion(in);
}
public VisibleRegion[] newArray(int size) {
return new VisibleRegion[size];
}
public VisibleRegion[] newArray(int size) {
return new VisibleRegion[size];
}
};
}

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.text.TextUtils;
import timber.log.Timber;
import com.mapbox.mapboxsdk.BuildConfig;
@@ -31,172 +32,175 @@ import okhttp3.internal.Util;
class HTTPRequest implements Callback {
private static OkHttpClient mClient = new OkHttpClient();
private String USER_AGENT_STRING = null;
private static OkHttpClient mClient = new OkHttpClient();
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;
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();
// Reentrancy is not needed, but "Lock" is an
// abstract class.
private ReentrantLock mLock = new ReentrantLock();
private long mNativePtr = 0;
private long mNativePtr = 0;
private Call mCall;
private Request mRequest;
private Call mCall;
private Request mRequest;
private native void nativeOnFailure(int type, String message);
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);
private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
String retryAfter, String xRateLimitReset, byte[] body);
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
mNativePtr = nativePtr;
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
mNativePtr = nativePtr;
try {
// Don't try a request if we aren't connected
if (!MapboxAccountManager.getInstance().isConnected()) {
throw new NoRouteToHostException("No Internet connection available.");
}
try {
// Don't try a request if we aren't connected
if (!MapboxAccountManager.getInstance().isConnected()) {
throw new NoRouteToHostException("No Internet connection available.");
}
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn") || host.endsWith(".mapbox.cn")) {
if (httpUrl.querySize() == 0) {
resourceUrl = resourceUrl + "?";
} else {
resourceUrl = resourceUrl + "&";
}
resourceUrl = resourceUrl + "events=true";
}
Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
} else if (modified.length() > 0) {
builder = builder.addHeader("If-Modified-Since", modified);
}
mRequest = builder.build();
mCall = mClient.newCall(mRequest);
mCall.enqueue(this);
} catch (Exception e) {
onFailure(e);
}
}
public void cancel() {
// mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
if (mCall != null) {
mCall.cancel();
}
// TODO: We need a lock here because we can try
// to cancel at the same time the request is getting
// 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();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Timber.v(String.format("[HTTP] Request was successful (code = %d).", response.code()));
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
|| host.endsWith(".mapbox.cn")) {
if (httpUrl.querySize() == 0) {
resourceUrl = resourceUrl + "?";
} 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(String.format(
"[HTTP] Request with response code = %d: %s",
response.code(), message));
resourceUrl = resourceUrl + "&";
}
resourceUrl = resourceUrl + "events=true";
}
byte[] body;
try {
body = response.body().bytes();
} catch (IOException e) {
onFailure(e);
//throw e;
return;
} finally {
response.body().close();
}
Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
} else if (modified.length() > 0) {
builder = builder.addHeader("If-Modified-Since", modified);
}
mRequest = builder.build();
mCall = mClient.newCall(mRequest);
mCall.enqueue(this);
} catch (Exception exception) {
onFailure(exception);
}
}
mLock.lock();
if (mNativePtr != 0) {
nativeOnResponse(response.code(),
response.header("ETag"),
response.header("Last-Modified"),
response.header("Cache-Control"),
response.header("Expires"),
response.header("Retry-After"),
response.header("x-rate-limit-reset"),
body);
}
mLock.unlock();
public void cancel() {
// mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
if (mCall != null) {
mCall.cancel();
}
@Override
public void onFailure(Call call, IOException e) {
onFailure(e);
// TODO: We need a lock here because we can try
// to cancel at the same time the request is getting
// 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();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Timber.v(String.format("[HTTP] Request was successful (code = %d).", 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(String.format(
"[HTTP] Request with response code = %d: %s",
response.code(), message));
}
private void onFailure(Exception e) {
int type = PERMANENT_ERROR;
if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException) || (e instanceof ProtocolException) || (e instanceof SSLException)) {
type = CONNECTION_ERROR;
} else if ((e instanceof InterruptedIOException)) {
type = TEMPORARY_ERROR;
}
String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
if (type == TEMPORARY_ERROR) {
Timber.d(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a temporary error: %s", errorMessage));
} else if (type == CONNECTION_ERROR) {
Timber.i(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a connection error: %s", errorMessage));
} else {
// PERMANENT_ERROR
Timber.w(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a permanent error: %s", errorMessage));
}
mLock.lock();
if (mNativePtr != 0) {
nativeOnFailure(type, errorMessage);
}
mLock.unlock();
byte[] body;
try {
body = response.body().bytes();
} catch (IOException ioException) {
onFailure(ioException);
//throw ioException;
return;
} finally {
response.body().close();
}
private String getUserAgent() {
if (USER_AGENT_STRING == null) {
return USER_AGENT_STRING = Util.toHumanReadableAscii(
String.format("%s %s (%s) Android/%s (%s)",
getApplicationIdentifier(),
BuildConfig.MAPBOX_VERSION_STRING,
BuildConfig.GIT_REVISION_SHORT,
Build.VERSION.SDK_INT,
Build.CPU_ABI)
);
} else {
return USER_AGENT_STRING;
}
mLock.lock();
if (mNativePtr != 0) {
nativeOnResponse(response.code(),
response.header("ETag"),
response.header("Last-Modified"),
response.header("Cache-Control"),
response.header("Expires"),
response.header("Retry-After"),
response.header("x-rate-limit-reset"),
body);
}
mLock.unlock();
}
@Override
public void onFailure(Call call, IOException e) {
onFailure(e);
}
private void onFailure(Exception e) {
int type = PERMANENT_ERROR;
if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException)
|| (e instanceof ProtocolException) || (e instanceof SSLException)) {
type = CONNECTION_ERROR;
} else if ((e instanceof InterruptedIOException)) {
type = TEMPORARY_ERROR;
}
private String getApplicationIdentifier() {
try {
Context context = MapboxAccountManager.getInstance().getApplicationContext();
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
} catch (Exception e) {
return "";
}
String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
if (type == TEMPORARY_ERROR) {
Timber.d(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a temporary error: %s", errorMessage));
} else if (type == CONNECTION_ERROR) {
Timber.i(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a connection error: %s", errorMessage));
} else {
// PERMANENT_ERROR
Timber.w(String.format(MapboxConstants.MAPBOX_LOCALE,
"Request failed due to a permanent error: %s", errorMessage));
}
mLock.lock();
if (mNativePtr != 0) {
nativeOnFailure(type, errorMessage);
}
mLock.unlock();
}
private String getUserAgent() {
if (USER_AGENT_STRING == null) {
return USER_AGENT_STRING = Util.toHumanReadableAscii(
String.format("%s %s (%s) Android/%s (%s)",
getApplicationIdentifier(),
BuildConfig.MAPBOX_VERSION_STRING,
BuildConfig.GIT_REVISION_SHORT,
Build.VERSION.SDK_INT,
Build.CPU_ABI)
);
} else {
return USER_AGENT_STRING;
}
}
private String getApplicationIdentifier() {
try {
Context context = MapboxAccountManager.getInstance().getApplicationContext();
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
} catch (Exception exception) {
return "";
}
}
}

View File

@@ -7,10 +7,11 @@ import android.location.Location;
*/
public interface LocationListener {
/**
* Callback method for receiving location updates from LocationServices.
* @param location The new Location data
*/
void onLocationChanged(Location location);
/**
* Callback method for receiving location updates from LocationServices.
*
* @param location The new Location data
*/
void onLocationChanged(Location location);
}

View File

@@ -8,6 +8,7 @@ import android.location.Location;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import timber.log.Timber;
import com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver;
@@ -19,169 +20,174 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Manages locational updates. Contains methods to register and unregister location listeners.
* <ul>
* <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive location updates.</li>
* <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive
* location updates.</li>
* <li> You can unregister a {@link LocationListener} with {@link #removeLocationListener(LocationListener)}.</li>
* </ul>
* <p>
* Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in Activity.onStop().
* (You won't receive location updates when paused, and this will cut down on unnecessary system overhead).
* Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack.
* Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in
* Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system
* overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back
* in the history stack.
* </p>
*/
public class LocationServices implements com.mapzen.android.lost.api.LocationListener {
private static LocationServices instance;
private static LocationServices instance;
private Context context;
private LostApiClient locationClient;
private Location lastLocation;
private Context context;
private LostApiClient locationClient;
private Location lastLocation;
private CopyOnWriteArrayList<LocationListener> locationListeners;
private CopyOnWriteArrayList<LocationListener> locationListeners;
private boolean isGPSEnabled;
private boolean isGpsEnabled;
/**
* Private constructor for singleton LocationServices
*/
private LocationServices(Context context) {
super();
this.context = context;
// Setup location services
locationClient = new LostApiClient.Builder(context).build();
locationListeners = new CopyOnWriteArrayList<>();
/**
* Private constructor for singleton LocationServices
*/
private LocationServices(Context context) {
super();
this.context = context;
// Setup location services
locationClient = new LostApiClient.Builder(context).build();
locationListeners = new CopyOnWriteArrayList<>();
}
/**
* Primary (singleton) access method for LocationServices
*
* @param context Context
* @return LocationServices
*/
public static LocationServices getLocationServices(@NonNull final Context context) {
if (instance == null) {
instance = new LocationServices(context.getApplicationContext());
}
return instance;
}
/**
* Enabled / Disable GPS focused location tracking
*
* @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
*/
public void toggleGPS(boolean enableGPS) {
if (!areLocationPermissionsGranted()) {
Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
return;
}
/**
* Primary (singleton) access method for LocationServices
*
* @param context Context
* @return LocationServices
*/
public static LocationServices getLocationServices(@NonNull final Context context) {
if (instance == null) {
instance = new LocationServices(context.getApplicationContext());
}
return instance;
// Disconnect
if (locationClient.isConnected()) {
// Disconnect first to ensure that the new requests are GPS
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
locationClient.disconnect();
}
/**
* Enabled / Disable GPS focused location tracking
*
* @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
*/
public void toggleGPS(boolean enableGPS) {
if (!areLocationPermissionsGranted()) {
Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
return;
}
// Disconnect
if (locationClient.isConnected()) {
// Disconnect first to ensure that the new requests are GPS
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
locationClient.disconnect();
}
// Setup Fresh
locationClient.connect();
Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
if (lastLocation != null) {
this.lastLocation = lastLocation;
}
LocationRequest locationRequest;
if (enableGPS) {
// LocationRequest Tuned for GPS
locationRequest = LocationRequest.create()
.setFastestInterval(1000)
.setSmallestDisplacement(3.0f)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
} else {
// LocationRequest Tuned for PASSIVE
locationRequest = LocationRequest.create()
.setFastestInterval(1000)
.setSmallestDisplacement(3.0f)
.setPriority(LocationRequest.PRIORITY_NO_POWER);
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
}
isGPSEnabled = enableGPS;
// Setup Fresh
locationClient.connect();
Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
if (lastLocation != null) {
this.lastLocation = lastLocation;
}
/**
* Returns if the GPS sensor is currently enabled
*
* @return active state of the GPS
*/
public boolean isGPSEnabled() {
return isGPSEnabled;
LocationRequest locationRequest;
if (enableGPS) {
// LocationRequest Tuned for GPS
locationRequest = LocationRequest.create()
.setFastestInterval(1000)
.setSmallestDisplacement(3.0f)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
} else {
// LocationRequest Tuned for PASSIVE
locationRequest = LocationRequest.create()
.setFastestInterval(1000)
.setSmallestDisplacement(3.0f)
.setPriority(LocationRequest.PRIORITY_NO_POWER);
com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
}
/**
* Called when the location has changed.
*
* @param location The updated location
*/
@Override
public void onLocationChanged(Location location) {
// Timber.d("onLocationChanged()..." + location);
this.lastLocation = location;
isGpsEnabled = enableGPS;
}
// Update Listeners
for (LocationListener listener : this.locationListeners) {
listener.onLocationChanged(location);
}
/**
* Returns if the GPS sensor is currently enabled
*
* @return active state of the GPS
*/
public boolean isGpsEnabled() {
return isGpsEnabled;
}
// Update the Telemetry Receiver
Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
context.sendBroadcast(locIntent);
/**
* Called when the location has changed.
*
* @param location The updated location
*/
@Override
public void onLocationChanged(Location location) {
// Timber.d("onLocationChanged()..." + location);
this.lastLocation = location;
// Update Listeners
for (LocationListener listener : this.locationListeners) {
listener.onLocationChanged(location);
}
/**
* Last known location
*
* @return Last known location data
*/
public Location getLastLocation() {
return lastLocation;
}
// Update the Telemetry Receiver
Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
context.sendBroadcast(locIntent);
}
/**
* Registers a LocationListener to receive location updates
*
* @param locationListener LocationListener
*/
public void addLocationListener(@NonNull LocationListener locationListener) {
if (!this.locationListeners.contains(locationListener)) {
this.locationListeners.add(locationListener);
}
}
/**
* Last known location
*
* @return Last known location data
*/
public Location getLastLocation() {
return lastLocation;
}
/**
* Unregister a LocationListener to stop receiving location updates
*
* @param locationListener LocationListener to remove
* @return True if LocationListener was found and removed, False if it was not
*/
public boolean removeLocationListener(@NonNull LocationListener locationListener) {
return this.locationListeners.remove(locationListener);
/**
* Registers a LocationListener to receive location updates
*
* @param locationListener LocationListener
*/
public void addLocationListener(@NonNull LocationListener locationListener) {
if (!this.locationListeners.contains(locationListener)) {
this.locationListeners.add(locationListener);
}
}
/**
* Check status of Location Permissions
* @return True if granted to the app, False if not
*/
public boolean areLocationPermissionsGranted() {
if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) &&
(ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
return false;
}
return true;
/**
* Unregister a LocationListener to stop receiving location updates
*
* @param locationListener LocationListener to remove
* @return True if LocationListener was found and removed, False if it was not
*/
public boolean removeLocationListener(@NonNull LocationListener locationListener) {
return this.locationListeners.remove(locationListener);
}
/**
* Check status of Location Permissions
*
* @return True if granted to the app, False if not
*/
public boolean areLocationPermissionsGranted() {
if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
&& (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
return false;
}
return true;
}
}

View File

@@ -4,5 +4,5 @@ import android.graphics.PointF;
public interface FocalPointChangeListener {
void onFocalPointChanged(PointF pointF);
void onFocalPointChanged(PointF pointF);
}

View File

@@ -26,133 +26,133 @@ import java.util.List;
*/
class IconManager {
private NativeMapView nativeMapView;
private List<Icon> icons;
private NativeMapView nativeMapView;
private List<Icon> icons;
private int averageIconHeight;
private int averageIconWidth;
private int averageIconHeight;
private int averageIconWidth;
IconManager(NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
this.icons = new ArrayList<>();
// load transparent icon for MarkerView to trace actual markers, see #6352
loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
IconManager(NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
this.icons = new ArrayList<>();
// load transparent icon for MarkerView to trace actual markers, see #6352
loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
}
Icon loadIconForMarker(Marker marker) {
Icon icon = marker.getIcon();
// calculating average before adding
int iconSize = icons.size() + 1;
// TODO replace former if case with anchor implementation,
// current workaround for having extra pixels is diving height by 2
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
marker.setIcon(icon);
} else {
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
}
Icon loadIconForMarker(Marker marker) {
Icon icon = marker.getIcon();
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
}
// calculating average before adding
int iconSize = icons.size() + 1;
Icon loadIconForMarkerView(MarkerView marker) {
Icon icon = marker.getIcon();
int iconSize = icons.size() + 1;
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarkerView();
marker.setIcon(icon);
}
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
if (!icons.contains(icon)) {
icons.add(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
}
// TODO replace former if case with anchor implementation,
// current workaround for having extra pixels is diving height by 2
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
marker.setIcon(icon);
} else {
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
}
int getTopOffsetPixelsForIcon(Icon icon) {
return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio());
}
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
}
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
bitmap.copyPixelsToBuffer(buffer);
float density = bitmap.getDensity();
if (density == Bitmap.DENSITY_NONE) {
density = DisplayMetrics.DENSITY_DEFAULT;
}
float scale = density / DisplayMetrics.DENSITY_DEFAULT;
nativeMapView.addAnnotationIcon(
id,
bitmap.getWidth(),
bitmap.getHeight(),
scale, buffer.array());
}
void reloadIcons() {
int count = icons.size();
for (int i = 0; i < count; i++) {
Icon icon = icons.get(i);
loadIcon(icon);
}
}
void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
marker.setIcon(icon);
}
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
Icon loadIconForMarkerView(MarkerView marker) {
Icon icon = marker.getIcon();
int iconSize = icons.size() + 1;
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarkerView();
marker.setIcon(icon);
}
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
if (!icons.contains(icon)) {
icons.add(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
// this seems to be a costly operation according to the profiler so I'm trying to save some calls
Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null;
if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
int getTopOffsetPixelsForIcon(Icon icon) {
return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio());
}
int getAverageIconHeight() {
return averageIconHeight;
}
void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
}
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
bitmap.copyPixelsToBuffer(buffer);
float density = bitmap.getDensity();
if (density == Bitmap.DENSITY_NONE) {
density = DisplayMetrics.DENSITY_DEFAULT;
}
float scale = density / DisplayMetrics.DENSITY_DEFAULT;
nativeMapView.addAnnotationIcon(
id,
bitmap.getWidth(),
bitmap.getHeight(),
scale, buffer.array());
}
void reloadIcons() {
int count = icons.size();
for (int i = 0; i < count; i++) {
Icon icon = icons.get(i);
loadIcon(icon);
}
}
void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
marker.setIcon(icon);
}
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
// this seems to be a costly operation according to the profiler so I'm trying to save some calls
Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null;
if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
int getAverageIconHeight() {
return averageIconHeight;
}
int getAverageIconWidth() {
return averageIconWidth;
}
int getAverageIconWidth() {
return averageIconWidth;
}
}

View File

@@ -15,73 +15,74 @@ import java.util.List;
* <p>
* Maintains a {@link List} of opened {@link InfoWindow} and tracks configurations as
* allowConcurrentMultipleInfoWindows which allows to have multiple {@link InfoWindow} open at the
* same time. Responsible for managing listeners as {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowClickListener}
* same time. Responsible for managing listeners as
* {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowClickListener}
* and {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowLongClickListener}.
* </p>
*/
class InfoWindowManager {
private List<InfoWindow> infoWindows;
private MapboxMap.InfoWindowAdapter infoWindowAdapter;
private boolean allowConcurrentMultipleInfoWindows;
private List<InfoWindow> infoWindows;
private MapboxMap.InfoWindowAdapter infoWindowAdapter;
private boolean allowConcurrentMultipleInfoWindows;
private MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener;
private MapboxMap.OnInfoWindowLongClickListener onInfoWindowLongClickListener;
private MapboxMap.OnInfoWindowCloseListener onInfoWindowCloseListener;
private MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener;
private MapboxMap.OnInfoWindowLongClickListener onInfoWindowLongClickListener;
private MapboxMap.OnInfoWindowCloseListener onInfoWindowCloseListener;
InfoWindowManager() {
this.infoWindows = new ArrayList<>();
}
InfoWindowManager() {
this.infoWindows = new ArrayList<>();
}
void setInfoWindowAdapter(@Nullable MapboxMap.InfoWindowAdapter infoWindowAdapter) {
this.infoWindowAdapter = infoWindowAdapter;
}
void setInfoWindowAdapter(@Nullable MapboxMap.InfoWindowAdapter infoWindowAdapter) {
this.infoWindowAdapter = infoWindowAdapter;
}
MapboxMap.InfoWindowAdapter getInfoWindowAdapter() {
return infoWindowAdapter;
}
MapboxMap.InfoWindowAdapter getInfoWindowAdapter() {
return infoWindowAdapter;
}
void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
allowConcurrentMultipleInfoWindows = allow;
}
void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
allowConcurrentMultipleInfoWindows = allow;
}
boolean isAllowConcurrentMultipleOpenInfoWindows() {
return allowConcurrentMultipleInfoWindows;
}
boolean isAllowConcurrentMultipleOpenInfoWindows() {
return allowConcurrentMultipleInfoWindows;
}
List<InfoWindow> getInfoWindows() {
return infoWindows;
}
List<InfoWindow> getInfoWindows() {
return infoWindows;
}
boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
}
boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
}
void setOnInfoWindowClickListener(@Nullable MapboxMap.OnInfoWindowClickListener listener) {
onInfoWindowClickListener = listener;
}
void setOnInfoWindowClickListener(@Nullable MapboxMap.OnInfoWindowClickListener listener) {
onInfoWindowClickListener = listener;
}
MapboxMap.OnInfoWindowClickListener getOnInfoWindowClickListener() {
return onInfoWindowClickListener;
}
MapboxMap.OnInfoWindowClickListener getOnInfoWindowClickListener() {
return onInfoWindowClickListener;
}
void setOnInfoWindowLongClickListener(@Nullable MapboxMap.OnInfoWindowLongClickListener listener) {
onInfoWindowLongClickListener = listener;
}
void setOnInfoWindowLongClickListener(@Nullable MapboxMap.OnInfoWindowLongClickListener listener) {
onInfoWindowLongClickListener = listener;
}
MapboxMap.OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
return onInfoWindowLongClickListener;
}
MapboxMap.OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
return onInfoWindowLongClickListener;
}
void setOnInfoWindowCloseListener(@Nullable MapboxMap.OnInfoWindowCloseListener listener) {
onInfoWindowCloseListener = listener;
}
void setOnInfoWindowCloseListener(@Nullable MapboxMap.OnInfoWindowCloseListener listener) {
onInfoWindowCloseListener = listener;
}
MapboxMap.OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
return onInfoWindowCloseListener;
}
MapboxMap.OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
return onInfoWindowCloseListener;
}
public void add(InfoWindow infoWindow) {
infoWindows.add(infoWindow);
}
public void add(InfoWindow infoWindow) {
infoWindows.add(infoWindow);
}
}

View File

@@ -35,196 +35,197 @@ import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
*/
public final class MapFragment extends Fragment {
private MapView map;
private OnMapReadyCallback onMapReadyCallback;
private MapView map;
private OnMapReadyCallback onMapReadyCallback;
/**
* Creates a MapFragment instance
*
* @param mapboxMapOptions The configuration options to be used.
* @return MapFragment created.
*/
public static MapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
MapFragment mapFragment = new MapFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
mapFragment.setArguments(bundle);
return mapFragment;
/**
* Creates a MapFragment instance
*
* @param mapboxMapOptions The configuration options to be used.
* @return MapFragment created.
*/
public static MapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
MapFragment mapFragment = new MapFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
mapFragment.setArguments(bundle);
return mapFragment;
}
/**
* Creates the fragment view hierarchy.
*
* @param inflater Inflater used to inflate content.
* @param container The parent layout for the map fragment.
* @param savedInstanceState The saved instance state for the map fragment.
* @return The view created
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Context context = inflater.getContext();
MapboxMapOptions options = null;
// Get bundle
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
/**
* Creates the fragment view hierarchy.
*
* @param inflater Inflater used to inflate content.
* @param container The parent layout for the map fragment.
* @param savedInstanceState The saved instance state for the map fragment.
* @return The view created
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Context context = inflater.getContext();
MapboxMapOptions options = null;
// Get bundle
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
// Assign an AccessToken if needed
if (options == null || options.getAccessToken() == null) {
String token = null;
if (MapboxAccountManager.getInstance() != null) {
token = MapboxAccountManager.getInstance().getAccessToken();
} else {
token = getToken(inflater.getContext());
}
if (TextUtils.isEmpty(token)) {
throw new InvalidAccessTokenException();
}
if (options == null) {
options = new MapboxMapOptions().accessToken(token);
} else {
options.accessToken(token);
}
}
Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
if (foregroundDrawable == null || foregroundBearingDrawable == null) {
if (foregroundDrawable == null) {
foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
}
if (foregroundBearingDrawable == null) {
foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
}
options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
if (options.getMyLocationBackgroundDrawable() == null) {
options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
return map = new MapView(inflater.getContext(), options);
// Assign an AccessToken if needed
if (options == null || options.getAccessToken() == null) {
String token = null;
if (MapboxAccountManager.getInstance() != null) {
token = MapboxAccountManager.getInstance().getAccessToken();
} else {
token = getToken(inflater.getContext());
}
if (TextUtils.isEmpty(token)) {
throw new InvalidAccessTokenException();
}
if (options == null) {
options = new MapboxMapOptions().accessToken(token);
} else {
options.accessToken(token);
}
}
/**
* <p>
* Returns the Mapbox access token set in the app resources.
* </p>
* It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
* meta-data value. If not found it will then attempt to load the access token from the
* {@code res/raw/token.txt} development file.
*
* @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
* @return The Mapbox access token or null if not found.
* @see MapboxConstants#KEY_META_DATA_MANIFEST
*
* @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
private String getToken(@NonNull Context context) {
try {
// read out AndroidManifest
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
if (token == null || token.isEmpty()) {
throw new IllegalArgumentException();
}
return token;
} catch (Exception e) {
// use fallback on string resource, used for development
int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
return tokenResId != 0 ? context.getString(tokenResId) : null;
}
Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
if (foregroundDrawable == null || foregroundBearingDrawable == null) {
if (foregroundDrawable == null) {
foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
}
if (foregroundBearingDrawable == null) {
foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
}
options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
/**
* Called when the fragment view hierarchy is created.
*
* @param view The content view of the fragment
* @param savedInstanceState THe saved instance state of the framgnt
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
map.onCreate(savedInstanceState);
if (options.getMyLocationBackgroundDrawable() == null) {
options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
/**
* Called when the fragment is visible for the users.
*/
@Override
public void onStart() {
super.onStart();
map.onStart();
map.getMapAsync(onMapReadyCallback);
}
return map = new MapView(inflater.getContext(), options);
}
/**
* Called when the fragment is ready to be interacted with.
*/
@Override
public void onResume() {
super.onResume();
map.onResume();
/**
* <p>
* Returns the Mapbox access token set in the app resources.
* </p>
* It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
* meta-data value. If not found it will then attempt to load the access token from the
* {@code res/raw/token.txt} development file.
*
* @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
* @return The Mapbox access token or null if not found.
* @see MapboxConstants#KEY_META_DATA_MANIFEST
* @deprecated As of release 4.1.0, replaced by
* {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
private String getToken(@NonNull Context context) {
try {
// read out AndroidManifest
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
if (token == null || token.isEmpty()) {
throw new IllegalArgumentException();
}
return token;
} catch (Exception exception) {
// use fallback on string resource, used for development
int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
return tokenResId != 0 ? context.getString(tokenResId) : null;
}
}
/**
* Called when the fragment is pausing.
*/
@Override
public void onPause() {
super.onPause();
map.onPause();
}
/**
* Called when the fragment view hierarchy is created.
*
* @param view The content view of the fragment
* @param savedInstanceState THe saved instance state of the framgnt
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
map.onCreate(savedInstanceState);
}
/**
* Called when the fragment state needs to be saved.
*
* @param outState The saved state
*/
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
map.onSaveInstanceState(outState);
}
/**
* Called when the fragment is visible for the users.
*/
@Override
public void onStart() {
super.onStart();
map.onStart();
map.getMapAsync(onMapReadyCallback);
}
/**
* Called when the fragment is no longer visible for the user.
*/
@Override
public void onStop() {
super.onStop();
map.onStop();
}
/**
* Called when the fragment is ready to be interacted with.
*/
@Override
public void onResume() {
super.onResume();
map.onResume();
}
/**
* Called when the fragment receives onLowMemory call from the hosting Activity.
*/
@Override
public void onLowMemory() {
super.onLowMemory();
map.onLowMemory();
}
/**
* Called when the fragment is pausing.
*/
@Override
public void onPause() {
super.onPause();
map.onPause();
}
/**
* Called when the fragment is view hiearchy is being destroyed.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
map.onDestroy();
}
/**
* Called when the fragment state needs to be saved.
*
* @param outState The saved state
*/
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
map.onSaveInstanceState(outState);
}
/**
* Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
*
* @param onMapReadyCallback The callback to be invoked.
*/
public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
this.onMapReadyCallback = onMapReadyCallback;
}
/**
* Called when the fragment is no longer visible for the user.
*/
@Override
public void onStop() {
super.onStop();
map.onStop();
}
/**
* Called when the fragment receives onLowMemory call from the hosting Activity.
*/
@Override
public void onLowMemory() {
super.onLowMemory();
map.onLowMemory();
}
/**
* Called when the fragment is view hiearchy is being destroyed.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
map.onDestroy();
}
/**
* Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
*
* @param onMapReadyCallback The callback to be invoked.
*/
public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
this.onMapReadyCallback = onMapReadyCallback;
}
}

View File

@@ -18,247 +18,248 @@ import android.view.ViewConfiguration;
*/
final class MapKeyListener {
private final TrackingSettings trackingSettings;
private final Transform transform;
private final UiSettings uiSettings;
private final TrackingSettings trackingSettings;
private final Transform transform;
private final UiSettings uiSettings;
private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
MapKeyListener(@NonNull Transform transform, @NonNull TrackingSettings trackingSettings, @NonNull UiSettings uiSettings) {
this.transform = transform;
this.trackingSettings = trackingSettings;
this.uiSettings = uiSettings;
}
MapKeyListener(@NonNull Transform transform, @NonNull TrackingSettings trackingSettings,
@NonNull UiSettings uiSettings) {
this.transform = transform;
this.trackingSettings = trackingSettings;
this.uiSettings = uiSettings;
}
/**
* Called when the user presses a key, alse called for repeated keys held down.
*
* @param keyCode the id of the pressed key
* @param event the related key event
* @return true if the wevent is handled
*/
boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
// If the user has held the scroll key down for a while then accelerate
// the scroll speed
double scrollDist = event.getRepeatCount() >= 5 ? 50.0 : 10.0;
/**
* Called when the user presses a key, alse called for repeated keys held down.
*
* @param keyCode the id of the pressed key
* @param event the related key event
* @return true if the wevent is handled
*/
boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
// If the user has held the scroll key down for a while then accelerate
// the scroll speed
double scrollDist = event.getRepeatCount() >= 5 ? 50.0 : 10.0;
// Check which key was pressed via hardware/real key code
switch (keyCode) {
// Tell the system to track these keys for long presses on
// onKeyLongPress is fired
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
event.startTracking();
return true;
// Check which key was pressed via hardware/real key code
switch (keyCode) {
// Tell the system to track these keys for long presses on
// onKeyLongPress is fired
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
event.startTracking();
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move left
transform.moveBy(scrollDist, 0.0, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move right
transform.moveBy(-scrollDist, 0.0, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_UP:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move up
transform.moveBy(0.0, scrollDist, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move down
transform.moveBy(0.0, -scrollDist, 0 /*no animation*/);
return true;
default:
// We are not interested in this key
return false;
}
}
/**
* Called when the user long presses a key that is being tracked.
*
* @param keyCode the id of the long pressed key
* @param event the related key event
* @return true if event is handled
*/
boolean onKeyLongPress(int keyCode, KeyEvent event) {
// Check which key was pressed via hardware/real key code
switch (keyCode) {
// Tell the system to track these keys for long presses on
// onKeyLongPress is fired
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Zoom out
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
return true;
default:
// We are not interested in this key
return false;
}
}
/**
* Called when the user releases a key.
*
* @param keyCode the id of the released key
* @param event the related key event
* @return true if the event is handled
*/
boolean onKeyUp(int keyCode, KeyEvent event) {
// Check if the key action was canceled (used for virtual keyboards)
if (event.isCanceled()) {
return false;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Check which key was pressed via hardware/real key code
// Note if keyboard does not have physical key (ie primary non-shifted
// key) then it will not appear here
// Must use the key character map as physical to character is not
// fixed/guaranteed
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Zoom in
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
return true;
// Move left
transform.moveBy(scrollDist, 0.0, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move right
transform.moveBy(-scrollDist, 0.0, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_UP:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move up
transform.moveBy(0.0, scrollDist, 0 /*no animation*/);
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Move down
transform.moveBy(0.0, -scrollDist, 0 /*no animation*/);
return true;
default:
// We are not interested in this key
return false;
}
}
/**
* Called for trackball events, all motions are relative in device specific units.
*
* @param event the related motion event
* @return true if the event is handled
*/
boolean onTrackballEvent(MotionEvent event) {
// Choose the action
switch (event.getActionMasked()) {
// The trackball was rotated
case MotionEvent.ACTION_MOVE:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Scroll the map
transform.moveBy(-10.0 * event.getX(), -10.0 * event.getY(), 0 /*no animation*/);
return true;
// Trackball was pushed in so start tracking and tell system we are
// interested
// We will then get the up action
case MotionEvent.ACTION_DOWN:
// Set up a delayed callback to check if trackball is still
// After waiting the system long press time out
if (currentTrackballLongPressTimeOut != null) {
currentTrackballLongPressTimeOut.cancel();
currentTrackballLongPressTimeOut = null;
}
currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut();
new Handler().postDelayed(currentTrackballLongPressTimeOut,
ViewConfiguration.getLongPressTimeout());
return true;
// Trackball was released
case MotionEvent.ACTION_UP:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Only handle if we have not already long pressed
if (currentTrackballLongPressTimeOut != null) {
// Zoom in
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
}
return true;
// Trackball was cancelled
case MotionEvent.ACTION_CANCEL:
if (currentTrackballLongPressTimeOut != null) {
currentTrackballLongPressTimeOut.cancel();
currentTrackballLongPressTimeOut = null;
}
return true;
default:
// We are not interested in this event
return false;
/**
* Called when the user long presses a key that is being tracked.
*
* @param keyCode the id of the long pressed key
* @param event the related key event
* @return true if event is handled
*/
boolean onKeyLongPress(int keyCode, KeyEvent event) {
// Check which key was pressed via hardware/real key code
switch (keyCode) {
// Tell the system to track these keys for long presses on
// onKeyLongPress is fired
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Zoom out
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
return true;
default:
// We are not interested in this key
return false;
}
}
/**
* Called when the user releases a key.
*
* @param keyCode the id of the released key
* @param event the related key event
* @return true if the event is handled
*/
boolean onKeyUp(int keyCode, KeyEvent event) {
// Check if the key action was canceled (used for virtual keyboards)
if (event.isCanceled()) {
return false;
}
/**
* This class implements the trackball long press time out callback
*/
private class TrackballLongPressTimeOut implements Runnable {
// Track if we have been cancelled
private boolean cancelled;
TrackballLongPressTimeOut() {
cancelled = false;
// Check which key was pressed via hardware/real key code
// Note if keyboard does not have physical key (ie primary non-shifted
// key) then it will not appear here
// Must use the key character map as physical to character is not
// fixed/guaranteed
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Cancel the timeout
public void cancel() {
cancelled = true;
}
// Called when long press time out expires
@Override
public void run() {
// Check if the trackball is still pressed
if (!cancelled) {
// Zoom out
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
// Ensure the up action is not run
currentTrackballLongPressTimeOut = null;
}
}
// Zoom in
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
return true;
}
// We are not interested in this key
return false;
}
/**
* Called for trackball events, all motions are relative in device specific units.
*
* @param event the related motion event
* @return true if the event is handled
*/
boolean onTrackballEvent(MotionEvent event) {
// Choose the action
switch (event.getActionMasked()) {
// The trackball was rotated
case MotionEvent.ACTION_MOVE:
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
}
// Cancel any animation
transform.cancelTransitions();
// Scroll the map
transform.moveBy(-10.0 * event.getX(), -10.0 * event.getY(), 0 /*no animation*/);
return true;
// Trackball was pushed in so start tracking and tell system we are
// interested
// We will then get the up action
case MotionEvent.ACTION_DOWN:
// Set up a delayed callback to check if trackball is still
// After waiting the system long press time out
if (currentTrackballLongPressTimeOut != null) {
currentTrackballLongPressTimeOut.cancel();
currentTrackballLongPressTimeOut = null;
}
currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut();
new Handler().postDelayed(currentTrackballLongPressTimeOut,
ViewConfiguration.getLongPressTimeout());
return true;
// Trackball was released
case MotionEvent.ACTION_UP:
if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
// Only handle if we have not already long pressed
if (currentTrackballLongPressTimeOut != null) {
// Zoom in
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
}
return true;
// Trackball was cancelled
case MotionEvent.ACTION_CANCEL:
if (currentTrackballLongPressTimeOut != null) {
currentTrackballLongPressTimeOut.cancel();
currentTrackballLongPressTimeOut = null;
}
return true;
default:
// We are not interested in this event
return false;
}
}
/**
* This class implements the trackball long press time out callback
*/
private class TrackballLongPressTimeOut implements Runnable {
// Track if we have been cancelled
private boolean cancelled;
TrackballLongPressTimeOut() {
cancelled = false;
}
// Cancel the timeout
public void cancel() {
cancelled = true;
}
// Called when long press time out expires
@Override
public void run() {
// Check if the trackball is still pressed
if (!cancelled) {
// Zoom out
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
// Ensure the up action is not run
currentTrackballLongPressTimeOut = null;
}
}
}
}

View File

@@ -4,16 +4,17 @@ package com.mapbox.mapboxsdk.maps;
* Interface definition for a callback to be invoked when the map is ready to be used.
* <p>
* Once an instance of this interface is set on a {@link MapFragment} or {@link MapView} object,
* the onMapReady(MapboxMap) method is triggered when the map is ready to be used and provides an instance of {@link MapboxMap}.
* the onMapReady(MapboxMap) method is triggered when the map is ready to be used and provides an instance of
* {@link MapboxMap}.
* </p>
*/
public interface OnMapReadyCallback {
/**
* Called when the map is ready to be used.
*
* @param mapboxMap An instance of MapboxMap associated with the {@link MapFragment} or
* {@link MapView} that defines the callback.
*/
void onMapReady(MapboxMap mapboxMap);
/**
* Called when the map is ready to be used.
*
* @param mapboxMap An instance of MapboxMap associated with the {@link MapFragment} or
* {@link MapView} that defines the callback.
*/
void onMapReady(MapboxMap mapboxMap);
}

View File

@@ -7,7 +7,6 @@ import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.geometry.VisibleRegion;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
/**
* A projection is used to translate between on screen location and geographic coordinates on
@@ -16,106 +15,106 @@ import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
*/
public class Projection {
private final NativeMapView nativeMapView;
private int[] contentPadding;
private final NativeMapView nativeMapView;
private int[] contentPadding;
Projection(@NonNull NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
this.contentPadding = new int[]{0, 0, 0, 0};
}
Projection(@NonNull NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
this.contentPadding = new int[] {0, 0, 0, 0};
}
void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
this.contentPadding = contentPadding;
void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
this.contentPadding = contentPadding;
int[] padding = new int[]{
contentPadding[0] + userLocationViewPadding[0],
contentPadding[1] + userLocationViewPadding[1],
contentPadding[2] + userLocationViewPadding[2],
contentPadding[3] + userLocationViewPadding[3]
};
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(padding);
}
int[] getContentPadding() {
return contentPadding;
}
int[] getContentPadding() {
return contentPadding;
}
public void invalidateContentPadding(int[] userLocationViewPadding) {
setContentPadding(contentPadding, userLocationViewPadding);
}
public void invalidateContentPadding(int[] userLocationViewPadding) {
setContentPadding(contentPadding, userLocationViewPadding);
}
/**
* <p>
* Returns the distance spanned by one pixel at the specified latitude and current zoom level.
* </p>
* The distance between pixels decreases as the latitude approaches the poles.
* This relationship parallels the relationship between longitudinal coordinates at different latitudes.
*
* @param latitude The latitude for which to return the value.
* @return The distance measured in meters.
*/
public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
return nativeMapView.getMetersPerPixelAtLatitude(latitude);
}
/**
* <p>
* Returns the distance spanned by one pixel at the specified latitude and current zoom level.
* </p>
* The distance between pixels decreases as the latitude approaches the poles.
* This relationship parallels the relationship between longitudinal coordinates at different latitudes.
*
* @param latitude The latitude for which to return the value.
* @return The distance measured in meters.
*/
public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
return nativeMapView.getMetersPerPixelAtLatitude(latitude);
}
/**
* Returns the geographic location that corresponds to a screen location.
* The screen location is specified in screen pixels (not display pixels) relative to the
* top left of the map (not the top left of the whole screen).
*
* @param point A Point on the screen in screen pixels.
* @return The LatLng corresponding to the point on the screen, or null if the ray through
* the given screen point does not intersect the ground plane.
*/
public LatLng fromScreenLocation(PointF point) {
return nativeMapView.latLngForPixel(point);
}
/**
* Returns the geographic location that corresponds to a screen location.
* The screen location is specified in screen pixels (not display pixels) relative to the
* top left of the map (not the top left of the whole screen).
*
* @param point A Point on the screen in screen pixels.
* @return The LatLng corresponding to the point on the screen, or null if the ray through
* the given screen point does not intersect the ground plane.
*/
public LatLng fromScreenLocation(PointF point) {
return nativeMapView.latLngForPixel(point);
}
/**
* Gets a projection of the viewing frustum for converting between screen coordinates and
* geo-latitude/longitude coordinates.
*
* @return The projection of the viewing frustum in its current state.
*/
public VisibleRegion getVisibleRegion() {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
/**
* Gets a projection of the viewing frustum for converting between screen coordinates and
* geo-latitude/longitude coordinates.
*
* @return The projection of the viewing frustum in its current state.
*/
public VisibleRegion getVisibleRegion() {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
float left = contentPadding[0];
float right = nativeMapView.getWidth() - contentPadding[2];
float top = contentPadding[1];
float bottom = nativeMapView.getHeight() - contentPadding[3];
float left = contentPadding[0];
float right = nativeMapView.getWidth() - contentPadding[2];
float top = contentPadding[1];
float bottom = nativeMapView.getHeight() - contentPadding[3];
LatLng topLeft = fromScreenLocation(new PointF(left, top));
LatLng topRight = fromScreenLocation(new PointF(right, top));
LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));
LatLng topLeft = fromScreenLocation(new PointF(left, top));
LatLng topRight = fromScreenLocation(new PointF(right, top));
LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));
builder.include(topLeft)
.include(topRight)
.include(bottomRight)
.include(bottomLeft);
builder.include(topLeft)
.include(topRight)
.include(bottomRight)
.include(bottomLeft);
return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
}
return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
}
/**
* Returns a screen location that corresponds to a geographical coordinate (LatLng).
* The screen location is in screen pixels (not display pixels) relative to the top left
* of the map (not of the whole screen).
*
* @param location A LatLng on the map to convert to a screen location.
* @return A Point representing the screen location in screen pixels.
*/
public PointF toScreenLocation(LatLng location) {
return nativeMapView.pixelForLatLng(location);
}
/**
* Returns a screen location that corresponds to a geographical coordinate (LatLng).
* The screen location is in screen pixels (not display pixels) relative to the top left
* of the map (not of the whole screen).
*
* @param location A LatLng on the map to convert to a screen location.
* @return A Point representing the screen location in screen pixels.
*/
public PointF toScreenLocation(LatLng location) {
return nativeMapView.pixelForLatLng(location);
}
float getHeight() {
return nativeMapView.getHeight();
}
float getHeight() {
return nativeMapView.getHeight();
}
float getWidth() {
return nativeMapView.getWidth();
}
float getWidth() {
return nativeMapView.getWidth();
}
}

View File

@@ -35,204 +35,206 @@ import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
*/
public class SupportMapFragment extends Fragment {
private MapView map;
private OnMapReadyCallback onMapReadyCallback;
private MapView map;
private OnMapReadyCallback onMapReadyCallback;
/**
* Creates a MapFragment instance
*
* @return MapFragment created
*/
public static SupportMapFragment newInstance() {
return new SupportMapFragment();
/**
* Creates a MapFragment instance
*
* @return MapFragment created
*/
public static SupportMapFragment newInstance() {
return new SupportMapFragment();
}
/**
* Creates a MapFragment instance
*
* @param mapboxMapOptions The configuration options to be used.
* @return MapFragment created.
*/
public static SupportMapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
SupportMapFragment mapFragment = new SupportMapFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
mapFragment.setArguments(bundle);
return mapFragment;
}
/**
* Creates the fragment view hierarchy.
*
* @param inflater Inflater used to inflate content.
* @param container The parent layout for the map fragment.
* @param savedInstanceState The saved instance state for the map fragment.
* @return The view created
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Context context = inflater.getContext();
MapboxMapOptions options = null;
// Get bundle
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
/**
* Creates a MapFragment instance
*
* @param mapboxMapOptions The configuration options to be used.
* @return MapFragment created.
*/
public static SupportMapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
SupportMapFragment mapFragment = new SupportMapFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
mapFragment.setArguments(bundle);
return mapFragment;
// Assign an AccessToken if needed
if (options == null || options.getAccessToken() == null) {
String token = null;
if (MapboxAccountManager.getInstance() != null) {
token = MapboxAccountManager.getInstance().getAccessToken();
} else {
token = getToken(inflater.getContext());
}
if (TextUtils.isEmpty(token)) {
throw new InvalidAccessTokenException();
}
if (options == null) {
options = new MapboxMapOptions().accessToken(token);
} else {
options.accessToken(token);
}
}
/**
* Creates the fragment view hierarchy.
*
* @param inflater Inflater used to inflate content.
* @param container The parent layout for the map fragment.
* @param savedInstanceState The saved instance state for the map fragment.
* @return The view created
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Context context = inflater.getContext();
MapboxMapOptions options = null;
// Get bundle
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
// Assign an AccessToken if needed
if (options == null || options.getAccessToken() == null) {
String token = null;
if (MapboxAccountManager.getInstance() != null) {
token = MapboxAccountManager.getInstance().getAccessToken();
} else {
token = getToken(inflater.getContext());
}
if (TextUtils.isEmpty(token)) {
throw new InvalidAccessTokenException();
}
if (options == null) {
options = new MapboxMapOptions().accessToken(token);
} else {
options.accessToken(token);
}
}
Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
if (foregroundDrawable == null || foregroundBearingDrawable == null) {
if (foregroundDrawable == null) {
foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
}
if (foregroundBearingDrawable == null) {
foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
}
options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
if (options.getMyLocationBackgroundDrawable() == null) {
options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
return map = new MapView(inflater.getContext(), options);
Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
if (foregroundDrawable == null || foregroundBearingDrawable == null) {
if (foregroundDrawable == null) {
foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
}
if (foregroundBearingDrawable == null) {
foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
}
options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
/**
* <p>
* Returns the Mapbox access token set in the app resources.
* </p>
* It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
* meta-data value. If not found it will then attempt to load the access token from the
* {@code res/raw/token.txt} development file.
*
* @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
* @return The Mapbox access token or null if not found.
* @see MapboxConstants#KEY_META_DATA_MANIFEST
* @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
private String getToken(@NonNull Context context) {
try {
// read out AndroidManifest
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
if (token == null || token.isEmpty()) {
throw new IllegalArgumentException();
}
return token;
} catch (Exception exception) {
// use fallback on string resource, used for development
int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
return tokenResId != 0 ? context.getString(tokenResId) : null;
}
if (options.getMyLocationBackgroundDrawable() == null) {
options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
/**
* Called when the fragment view hierarchy is created.
*
* @param view The content view of the fragment
* @param savedInstanceState THe saved instance state of the framgnt
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
map.onCreate(savedInstanceState);
}
return map = new MapView(inflater.getContext(), options);
}
/**
* Called when the fragment is visible for the users.
*/
@Override
public void onStart() {
super.onStart();
map.onStart();
map.getMapAsync(onMapReadyCallback);
/**
* <p>
* Returns the Mapbox access token set in the app resources.
* </p>
* It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
* meta-data value. If not found it will then attempt to load the access token from the
* {@code res/raw/token.txt} development file.
*
* @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
* @return The Mapbox access token or null if not found.
* @see MapboxConstants#KEY_META_DATA_MANIFEST
* @deprecated As of release 4.1.0, replaced by
* {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
*/
@Deprecated
private String getToken(@NonNull Context context) {
try {
// read out AndroidManifest
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
if (token == null || token.isEmpty()) {
throw new IllegalArgumentException();
}
return token;
} catch (Exception exception) {
// use fallback on string resource, used for development
int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
return tokenResId != 0 ? context.getString(tokenResId) : null;
}
}
/**
* Called when the fragment is ready to be interacted with.
*/
@Override
public void onResume() {
super.onResume();
map.onResume();
}
/**
* Called when the fragment view hierarchy is created.
*
* @param view The content view of the fragment
* @param savedInstanceState THe saved instance state of the framgnt
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
map.onCreate(savedInstanceState);
}
/**
* Called when the fragment is pausing.
*/
@Override
public void onPause() {
super.onPause();
map.onPause();
}
/**
* Called when the fragment is visible for the users.
*/
@Override
public void onStart() {
super.onStart();
map.onStart();
map.getMapAsync(onMapReadyCallback);
}
/**
* Called when the fragment state needs to be saved.
*
* @param outState The saved state
*/
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
map.onSaveInstanceState(outState);
}
/**
* Called when the fragment is ready to be interacted with.
*/
@Override
public void onResume() {
super.onResume();
map.onResume();
}
/**
* Called when the fragment is no longer visible for the user.
*/
@Override
public void onStop() {
super.onStop();
map.onStop();
}
/**
* Called when the fragment is pausing.
*/
@Override
public void onPause() {
super.onPause();
map.onPause();
}
/**
* Called when the fragment receives onLowMemory call from the hosting Activity.
*/
@Override
public void onLowMemory() {
super.onLowMemory();
map.onLowMemory();
}
/**
* Called when the fragment state needs to be saved.
*
* @param outState The saved state
*/
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
map.onSaveInstanceState(outState);
}
/**
* Called when the fragment is view hiearchy is being destroyed.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
map.onDestroy();
}
/**
* Called when the fragment is no longer visible for the user.
*/
@Override
public void onStop() {
super.onStop();
map.onStop();
}
/**
* Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
*
* @param onMapReadyCallback The callback to be invoked.
*/
public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
this.onMapReadyCallback = onMapReadyCallback;
}
/**
* Called when the fragment receives onLowMemory call from the hosting Activity.
*/
@Override
public void onLowMemory() {
super.onLowMemory();
map.onLowMemory();
}
/**
* Called when the fragment is view hiearchy is being destroyed.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
map.onDestroy();
}
/**
* Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
*
* @param onMapReadyCallback The callback to be invoked.
*/
public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
this.onMapReadyCallback = onMapReadyCallback;
}
}

View File

@@ -23,295 +23,298 @@ import timber.log.Timber;
*/
public final class TrackingSettings {
private final MyLocationView myLocationView;
private final UiSettings uiSettings;
private final FocalPointChangeListener focalPointChangedListener;
private LocationListener myLocationListener;
private final MyLocationView myLocationView;
private final UiSettings uiSettings;
private final FocalPointChangeListener focalPointChangedListener;
private LocationListener myLocationListener;
private boolean myLocationEnabled;
private boolean dismissLocationTrackingOnGesture = true;
private boolean dismissBearingTrackingOnGesture = true;
private boolean myLocationEnabled;
private boolean dismissLocationTrackingOnGesture = true;
private boolean dismissBearingTrackingOnGesture = true;
private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings, FocalPointChangeListener focalPointChangedListener) {
this.myLocationView = myLocationView;
this.focalPointChangedListener = focalPointChangedListener;
this.uiSettings = uiSettings;
TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings,
FocalPointChangeListener focalPointChangedListener) {
this.myLocationView = myLocationView;
this.focalPointChangedListener = focalPointChangedListener;
this.uiSettings = uiSettings;
}
/**
* <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.setMyLocationTrackingMode(myLocationTrackingMode);
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
myLocationView.getCenterY()));
} else {
focalPointChangedListener.onFocalPointChanged(null);
}
/**
* <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.setMyLocationTrackingMode(myLocationTrackingMode);
if (onMyLocationTrackingModeChangeListener != null) {
onMyLocationTrackingModeChangeListener.onMyLocationTrackingModeChange(myLocationTrackingMode);
}
}
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
} 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 the tracking modes will be dismissed when a gesture occurs.
*
* @return True to indicate the tracking modes will be dismissed.
* @deprecated use @link #isAllDismissTrackingOnGestureinstead
*/
@Deprecated
public boolean isDismissTrackingOnGesture() {
return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
}
/**
* 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 the tracking modes.
* @deprecated use @link #setDismissAllTrackingOnGesture instead
*/
@Deprecated
public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
setDismissAllTrackingOnGesture(dismissTrackingOnGesture);
}
/**
* 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);
}
/**
* Reset the tracking modes as necessary. Location tracking is reset if the map center is changed,
* bearing tracking if there is a rotation.
*/
void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
// if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture()) {
setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
}
// reset bearing tracking only on rotate
if (rotate && !isBearingTrackingDisabled() && isDismissBearingTrackingOnGesture()) {
setMyBearingTrackingMode(MyBearingTracking.NONE);
}
}
void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1);
}
Location getMyLocation() {
return myLocationView.getLocation();
}
void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
if (listener != null) {
myLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (listener != null) {
listener.onMyLocationChange(location);
}
}
};
LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener);
} else {
LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener);
myLocationListener = null;
}
}
/**
* 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 the tracking modes will be dismissed when a gesture occurs.
*
* @return True to indicate the tracking modes will be dismissed.
* @deprecated use @link #isAllDismissTrackingOnGestureinstead
*/
@Deprecated
public boolean isDismissTrackingOnGesture() {
return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
}
/**
* 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 the tracking modes.
* @deprecated use @link #setDismissAllTrackingOnGesture instead
*/
@Deprecated
public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
setDismissAllTrackingOnGesture(dismissTrackingOnGesture);
}
/**
* 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);
}
/**
* Reset the tracking modes as necessary. Location tracking is reset if the map center is changed,
* bearing tracking if there is a rotation.
*
* @param translate
* @param rotate
*/
void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
// if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture()) {
setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
}
// reset bearing tracking only on rotate
if (rotate && !isBearingTrackingDisabled() && isDismissBearingTrackingOnGesture()) {
setMyBearingTrackingMode(MyBearingTracking.NONE);
}
}
void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1);
}
Location getMyLocation() {
return myLocationView.getLocation();
}
void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
if (listener != null) {
myLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (listener != null) {
listener.onMyLocationChange(location);
}
}
};
LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener);
} else {
LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener);
myLocationListener = null;
}
}
boolean isPermissionsAccepted() {
return (ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener) {
this.onMyLocationTrackingModeChangeListener = onMyLocationTrackingModeChangeListener;
}
void setOnMyBearingTrackingModeChangeListener(MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener) {
this.onMyBearingTrackingModeChangeListener = onMyBearingTrackingModeChangeListener;
}
MyLocationView getMyLocationView() {
return myLocationView;
}
boolean isMyLocationEnabled() {
return myLocationEnabled;
}
void setMyLocationEnabled(boolean locationEnabled) {
if (!isPermissionsAccepted()) {
Timber.e("Could not activate user location tracking: "
+ "user did not accept the permission or permissions were not requested.");
return;
}
myLocationEnabled = locationEnabled;
myLocationView.setEnabled(locationEnabled);
boolean isPermissionsAccepted() {
return (ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
|| ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
}
void setOnMyLocationTrackingModeChangeListener(
MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener) {
this.onMyLocationTrackingModeChangeListener = onMyLocationTrackingModeChangeListener;
}
void setOnMyBearingTrackingModeChangeListener(
MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener) {
this.onMyBearingTrackingModeChangeListener = onMyBearingTrackingModeChangeListener;
}
MyLocationView getMyLocationView() {
return myLocationView;
}
boolean isMyLocationEnabled() {
return myLocationEnabled;
}
void setMyLocationEnabled(boolean locationEnabled) {
if (!isPermissionsAccepted()) {
Timber.e("Could not activate user location tracking: "
+ "user did not accept the permission or permissions were not requested.");
return;
}
myLocationEnabled = locationEnabled;
myLocationView.setEnabled(locationEnabled);
}
}

View File

@@ -21,275 +21,280 @@ import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED;
/**
* Resembles the current Map transformation.
* <p>
* Responsible for synchronising {@link CameraPosition} state and notifying {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}.
* Responsible for synchronising {@link CameraPosition} state and notifying
* {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}.
* </p>
*/
final class Transform implements MapView.OnMapChangedListener {
private final NativeMapView mapView;
private final MarkerViewManager markerViewManager;
private final TrackingSettings trackingSettings;
private final MyLocationView myLocationView;
private final NativeMapView mapView;
private final MarkerViewManager markerViewManager;
private final TrackingSettings trackingSettings;
private final MyLocationView myLocationView;
private CameraPosition cameraPosition;
private MapboxMap.CancelableCallback cameraCancelableCallback;
private MapboxMap.OnCameraChangeListener onCameraChangeListener;
private CameraPosition cameraPosition;
private MapboxMap.CancelableCallback cameraCancelableCallback;
private MapboxMap.OnCameraChangeListener onCameraChangeListener;
Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) {
this.mapView = mapView;
this.markerViewManager = markerViewManager;
this.trackingSettings = trackingSettings;
this.myLocationView = trackingSettings.getMyLocationView();
Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) {
this.mapView = mapView;
this.markerViewManager = markerViewManager;
this.trackingSettings = trackingSettings;
this.myLocationView = trackingSettings.getMyLocationView();
}
void initialise(@NonNull MapboxMap mapboxMap, @NonNull MapboxMapOptions options) {
CameraPosition position = options.getCamera();
if (position != null && !position.equals(CameraPosition.DEFAULT)) {
moveCamera(mapboxMap, CameraUpdateFactory.newCameraPosition(position), null);
}
}
//
// Camera API
//
@UiThread
public final CameraPosition getCameraPosition() {
if (cameraPosition == null) {
cameraPosition = invalidateCameraPosition();
}
return cameraPosition;
}
@UiThread
void updateCameraPosition(@NonNull CameraPosition position) {
if (myLocationView != null) {
myLocationView.setCameraPosition(position);
}
markerViewManager.setTilt((float) position.tilt);
}
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) {
invalidateCameraPosition();
if (cameraCancelableCallback != null) {
cameraCancelableCallback.onFinish();
cameraCancelableCallback = null;
}
mapView.removeOnMapChangedListener(this);
}
}
@UiThread
final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
cancelTransitions();
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
if (callback != null) {
callback.onFinish();
}
}
@UiThread
final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator,
boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
if (resetTrackingMode) {
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
}
void initialise(@NonNull MapboxMap mapboxMap, @NonNull MapboxMapOptions options) {
CameraPosition position = options.getCamera();
if (position != null && !position.equals(CameraPosition.DEFAULT)) {
moveCamera(mapboxMap, CameraUpdateFactory.newCameraPosition(position), null);
}
cancelTransitions();
if (callback != null) {
cameraCancelableCallback = callback;
mapView.addOnMapChangedListener(this);
}
//
// Camera API
//
mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
cameraPosition.zoom, easingInterpolator);
}
@UiThread
public final CameraPosition getCameraPosition() {
if (cameraPosition == null) {
cameraPosition = invalidateCameraPosition();
}
return cameraPosition;
@UiThread
final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs,
final MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
cancelTransitions();
if (callback != null) {
cameraCancelableCallback = callback;
mapView.addOnMapChangedListener(this);
}
@UiThread
void updateCameraPosition(@NonNull CameraPosition position) {
if (myLocationView != null) {
myLocationView.setCameraPosition(position);
}
markerViewManager.setTilt((float) position.tilt);
mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
cameraPosition.zoom);
}
@UiThread
@Nullable
CameraPosition invalidateCameraPosition() {
if (mapView != null) {
cameraPosition = new CameraPosition.Builder(mapView.getCameraValues()).build();
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
}
}
return cameraPosition;
}
void cancelTransitions() {
if (cameraCancelableCallback != null) {
cameraCancelableCallback.onCancel();
cameraCancelableCallback = null;
}
mapView.cancelTransitions();
}
@UiThread
void resetNorth() {
cancelTransitions();
mapView.resetNorth();
}
void setOnCameraChangeListener(@Nullable MapboxMap.OnCameraChangeListener listener) {
this.onCameraChangeListener = listener;
}
private long getDurationNano(long durationMs) {
return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
}
//
// non Camera API
//
// Zoom in or out
double getZoom() {
return cameraPosition.zoom;
}
void zoom(boolean zoomIn) {
zoom(zoomIn, -1.0f, -1.0f);
}
void zoom(boolean zoomIn, float x, float y) {
// Cancel any animation
cancelTransitions();
if (zoomIn) {
mapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION);
} else {
mapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION);
}
}
// Direction
double getBearing() {
double direction = -mapView.getBearing();
while (direction > 360) {
direction -= 360;
}
while (direction < 0) {
direction += 360;
}
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) {
invalidateCameraPosition();
if (cameraCancelableCallback != null) {
cameraCancelableCallback.onFinish();
cameraCancelableCallback = null;
}
mapView.removeOnMapChangedListener(this);
}
return direction;
}
double getRawBearing() {
return mapView.getBearing();
}
void setBearing(double bearing) {
if (myLocationView != null) {
myLocationView.setBearing(bearing);
}
mapView.setBearing(bearing);
}
@UiThread
final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
cancelTransitions();
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
if (callback != null) {
callback.onFinish();
}
void setBearing(double bearing, float focalX, float focalY) {
if (myLocationView != null) {
myLocationView.setBearing(bearing);
}
mapView.setBearing(bearing, focalX, focalY);
}
@UiThread
final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
if (resetTrackingMode) {
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
}
cancelTransitions();
if (callback != null) {
cameraCancelableCallback = callback;
mapView.addOnMapChangedListener(this);
}
//
// LatLng / CenterCoordinate
//
mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, cameraPosition.zoom, easingInterpolator);
LatLng getLatLng() {
return mapView.getLatLng();
}
//
// Pitch / Tilt
//
double getTilt() {
return mapView.getPitch();
}
void setTilt(Double pitch) {
if (myLocationView != null) {
myLocationView.setTilt(pitch);
}
markerViewManager.setTilt(pitch.floatValue());
mapView.setPitch(pitch, 0);
}
@UiThread
final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
cameraPosition = update.getCameraPosition(mapboxMap);
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
//
// Center coordinate
//
cancelTransitions();
if (callback != null) {
cameraCancelableCallback = callback;
mapView.addOnMapChangedListener(this);
}
LatLng getCenterCoordinate() {
return mapView.getLatLng();
}
mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, cameraPosition.zoom);
void setCenterCoordinate(LatLng centerCoordinate) {
mapView.setLatLng(centerCoordinate);
}
void setGestureInProgress(boolean gestureInProgress) {
mapView.setGestureInProgress(gestureInProgress);
if (!gestureInProgress) {
invalidateCameraPosition();
}
}
@UiThread
@Nullable
CameraPosition invalidateCameraPosition() {
if (mapView != null) {
cameraPosition = new CameraPosition.Builder(mapView.getCameraValues()).build();
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
}
}
return cameraPosition;
void zoomBy(double pow, float x, float y) {
mapView.scaleBy(pow, x, y);
}
void moveBy(double offsetX, double offsetY, long duration) {
mapView.moveBy(offsetX, offsetY, duration);
}
//
// Min & Max ZoomLevel
//
void setMinZoom(double minZoom) {
if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
Timber.e("Not setting minZoomPreference, value is in unsupported range: " + minZoom);
return;
}
mapView.setMinZoom(minZoom);
}
void cancelTransitions() {
if (cameraCancelableCallback != null) {
cameraCancelableCallback.onCancel();
cameraCancelableCallback = null;
}
mapView.cancelTransitions();
double getMinZoom() {
return mapView.getMinZoom();
}
void setMaxZoom(double maxZoom) {
if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
Timber.e("Not setting maxZoomPreference, value is in unsupported range: " + maxZoom);
return;
}
mapView.setMaxZoom(maxZoom);
}
@UiThread
void resetNorth() {
cancelTransitions();
mapView.resetNorth();
}
void setOnCameraChangeListener(@Nullable MapboxMap.OnCameraChangeListener listener) {
this.onCameraChangeListener = listener;
}
private long getDurationNano(long durationMs) {
return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
}
//
// non Camera API
//
// Zoom in or out
double getZoom() {
return cameraPosition.zoom;
}
void zoom(boolean zoomIn) {
zoom(zoomIn, -1.0f, -1.0f);
}
void zoom(boolean zoomIn, float x, float y) {
// Cancel any animation
cancelTransitions();
if (zoomIn) {
mapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION);
} else {
mapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION);
}
}
// Direction
double getBearing() {
double direction = -mapView.getBearing();
while (direction > 360) {
direction -= 360;
}
while (direction < 0) {
direction += 360;
}
return direction;
}
double getRawBearing(){
return mapView.getBearing();
}
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);
}
//
// LatLng / CenterCoordinate
//
LatLng getLatLng() {
return mapView.getLatLng();
}
//
// Pitch / Tilt
//
double getTilt() {
return mapView.getPitch();
}
void setTilt(Double pitch) {
if (myLocationView != null) {
myLocationView.setTilt(pitch);
}
markerViewManager.setTilt(pitch.floatValue());
mapView.setPitch(pitch, 0);
}
//
// Center coordinate
//
LatLng getCenterCoordinate() {
return mapView.getLatLng();
}
void setCenterCoordinate(LatLng centerCoordinate) {
mapView.setLatLng(centerCoordinate);
}
void setGestureInProgress(boolean gestureInProgress) {
mapView.setGestureInProgress(gestureInProgress);
if (!gestureInProgress) {
invalidateCameraPosition();
}
}
void zoomBy(double pow, float x, float y) {
mapView.scaleBy(pow, x, y);
}
void moveBy(double offsetX, double offsetY, long duration) {
mapView.moveBy(offsetX, offsetY, duration);
}
//
// Min & Max ZoomLevel
//
void setMinZoom(double minZoom) {
if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
Timber.e("Not setting minZoomPreference, value is in unsupported range: " + minZoom);
return;
}
mapView.setMinZoom(minZoom);
}
double getMinZoom() {
return mapView.getMinZoom();
}
void setMaxZoom(double maxZoom) {
if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
Timber.e("Not setting maxZoomPreference, value is in unsupported range: " + maxZoom);
return;
}
mapView.setMaxZoom(maxZoom);
}
double getMaxZoom() {
return mapView.getMaxZoom();
}
double getMaxZoom() {
return mapView.getMaxZoom();
}
}

View File

@@ -27,140 +27,140 @@ import java.lang.ref.WeakReference;
*/
public final class CompassView extends ImageView implements Runnable {
private static final long TIME_WAIT_IDLE = 500;
private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
private static final long TIME_MAP_NORTH_ANIMATION = 150;
private static final long TIME_WAIT_IDLE = 500;
private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
private static final long TIME_MAP_NORTH_ANIMATION = 150;
private double direction = 0.0;
private boolean fadeCompassViewFacingNorth = true;
private ViewPropertyAnimatorCompat fadeAnimator;
private double direction = 0.0;
private boolean fadeCompassViewFacingNorth = true;
private ViewPropertyAnimatorCompat fadeAnimator;
public CompassView(Context context) {
super(context);
initialize(context);
public CompassView(Context context) {
super(context);
initialize(context);
}
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context) {
setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.mapbox_compass_icon));
setContentDescription(getResources().getString(R.string.mapbox_compassContentDescription));
setEnabled(false);
// Layout params
float screenDensity = context.getResources().getDisplayMetrics().density;
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams((int) (48 * screenDensity), (int) (48 * screenDensity));
setLayoutParams(lp);
}
// TODO refactor MapboxMap and replace with interface
public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
setOnClickListener(new CompassClickListener(mapboxMap, this));
}
private void resetAnimation() {
if (fadeAnimator != null) {
fadeAnimator.cancel();
}
fadeAnimator = null;
}
public boolean isHidden() {
return fadeCompassViewFacingNorth && isFacingNorth();
}
public boolean isFacingNorth() {
// increase range more than just 0.0
return direction >= 359.0 || direction <= 1.0;
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (enabled && !isHidden()) {
resetAnimation();
setAlpha(1.0f);
setVisibility(View.VISIBLE);
} else {
resetAnimation();
setAlpha(0.0f);
setVisibility(View.INVISIBLE);
}
}
public void update(final double direction) {
this.direction = direction;
if (!isEnabled()) {
return;
}
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
if (isHidden()) {
if (getVisibility() == View.INVISIBLE || fadeAnimator != null) {
return;
}
postDelayed(this, TIME_WAIT_IDLE);
return;
} else {
resetAnimation();
setAlpha(1.0f);
setVisibility(View.VISIBLE);
}
public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
setRotation((float) direction);
}
private void initialize(Context context) {
setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.mapbox_compass_icon));
setContentDescription(getResources().getString(R.string.mapbox_compassContentDescription));
setEnabled(false);
public void fadeCompassViewFacingNorth(boolean compassFadeFacingNorth) {
fadeCompassViewFacingNorth = compassFadeFacingNorth;
}
// Layout params
float screenDensity = context.getResources().getDisplayMetrics().density;
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams((int) (48 * screenDensity), (int) (48 * screenDensity));
setLayoutParams(lp);
}
// TODO refactor MapboxMap and replace with interface
public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
setOnClickListener(new CompassClickListener(mapboxMap, this));
}
private void resetAnimation() {
if (fadeAnimator != null) {
fadeAnimator.cancel();
}
fadeAnimator = null;
}
public boolean isHidden() {
return fadeCompassViewFacingNorth && isFacingNorth();
}
public boolean isFacingNorth() {
// increase range more than just 0.0
return direction >= 359.0 || direction <= 1.0;
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (enabled && !isHidden()) {
resetAnimation();
setAlpha(1.0f);
setVisibility(View.VISIBLE);
} else {
resetAnimation();
setAlpha(0.0f);
setVisibility(View.INVISIBLE);
}
}
public void update(final double direction) {
this.direction = direction;
if (!isEnabled()) {
return;
}
if (isHidden()) {
if (getVisibility() == View.INVISIBLE || fadeAnimator != null) {
return;
}
postDelayed(this, TIME_WAIT_IDLE);
return;
} else {
resetAnimation();
setAlpha(1.0f);
setVisibility(View.VISIBLE);
}
setRotation((float) direction);
}
public void fadeCompassViewFacingNorth(boolean compassFadeFacingNorth) {
fadeCompassViewFacingNorth = compassFadeFacingNorth;
}
public boolean isFadeCompassViewFacingNorth(){
return fadeCompassViewFacingNorth;
}
@Override
public void run() {
if (isFacingNorth() && fadeCompassViewFacingNorth) {
resetAnimation();
setLayerType(View.LAYER_TYPE_HARDWARE, null);
fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION);
fadeAnimator.setListener(new ViewPropertyAnimatorListenerAdapter() {
@Override
public void onAnimationEnd(View view) {
setLayerType(LAYER_TYPE_NONE, null);
setVisibility(View.INVISIBLE);
resetAnimation();
}
});
}
}
static class CompassClickListener implements View.OnClickListener {
private WeakReference<MapboxMap> mapboxMap;
private WeakReference<CompassView> compassView;
CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
this.mapboxMap = new WeakReference<>(mapboxMap);
this.compassView = new WeakReference<>(compassView);
}
public boolean isFadeCompassViewFacingNorth() {
return fadeCompassViewFacingNorth;
}
@Override
public void run() {
if (isFacingNorth() && fadeCompassViewFacingNorth) {
resetAnimation();
setLayerType(View.LAYER_TYPE_HARDWARE, null);
fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION);
fadeAnimator.setListener(new ViewPropertyAnimatorListenerAdapter() {
@Override
public void onClick(View view) {
final MapboxMap mapboxMap = this.mapboxMap.get();
final CompassView compassView = this.compassView.get();
if (mapboxMap != null && compassView != null) {
mapboxMap.resetNorth();
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
}
public void onAnimationEnd(View view) {
setLayerType(LAYER_TYPE_NONE, null);
setVisibility(View.INVISIBLE);
resetAnimation();
}
});
}
}
static class CompassClickListener implements View.OnClickListener {
private WeakReference<MapboxMap> mapboxMap;
private WeakReference<CompassView> compassView;
CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
this.mapboxMap = new WeakReference<>(mapboxMap);
this.compassView = new WeakReference<>(compassView);
}
@Override
public void onClick(View view) {
final MapboxMap mapboxMap = this.mapboxMap.get();
final CompassView compassView = this.compassView.get();
if (mapboxMap != null && compassView != null) {
mapboxMap.resetNorth();
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
}
}
}
}

View File

@@ -17,280 +17,282 @@ import com.mapbox.mapboxsdk.maps.Projection;
*/
public class MyLocationViewSettings {
private Projection projection;
private MyLocationView myLocationView;
private FocalPointChangeListener focalPointChangeListener;
private Projection projection;
private MyLocationView myLocationView;
private FocalPointChangeListener focalPointChangeListener;
//
// State
//
//
// State
//
private boolean enabled;
private boolean enabled;
//
// Foreground
//
//
// Foreground
//
private Drawable foregroundDrawable;
private Drawable foregroundBearingDrawable;
private Drawable foregroundDrawable;
private Drawable foregroundBearingDrawable;
@ColorInt
private int foregroundTintColor;
@ColorInt
private int foregroundTintColor;
//
// Background
//
//
// Background
//
private Drawable backgroundDrawable;
private int[] backgroundOffset = new int[4];
private Drawable backgroundDrawable;
private int[] backgroundOffset = new int[4];
@ColorInt
private int backgroundTintColor;
@ColorInt
private int backgroundTintColor;
//
// Accuracy
//
//
// Accuracy
//
private int accuracyAlpha;
private int accuracyAlpha;
@ColorInt
private int accuracyTintColor;
@ColorInt
private int accuracyTintColor;
//
// Padding
//
//
// Padding
//
private int[] padding = new int[4];
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;
/**
* 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;
}
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());
}
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());
}
/**
* Returns if the MyLocationView is enabled
*
* @return true if MyLocationView is enabled,
*/
public boolean isEnabled() {
return enabled;
}
/**
* 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 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>
*
* @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);
}
/**
* Set the foreground drawable of the MyLocationView
* <p>
* The foreground drawable is the image visible on screen
* </p>
*
* @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);
}
/**
* 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 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;
}
/**
* 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
*/
public void setForegroundTintColor(@ColorInt int foregroundTintColor) {
this.foregroundTintColor = foregroundTintColor;
myLocationView.setForegroundDrawableTint(foregroundTintColor);
}
/**
* 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
*/
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;
}
/**
* 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>
*
* @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);
}
}
/**
* Set the background drawable of MyLocationView
* <p>
* Padding can be added to provide an offset to the background
* </p>
*
* @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);
}
}
/**
* Get the background drawable of MyLocationView.
*
* @return the drawable used as background
*/
public Drawable getBackgroundDrawable() {
return backgroundDrawable;
}
/**
* 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
*/
public void setBackgroundTintColor(@ColorInt int backgroundTintColor) {
this.backgroundTintColor = backgroundTintColor;
myLocationView.setShadowDrawableTint(backgroundTintColor);
}
/**
* Set the background tint color.
*
* @param backgroundTintColor the color to tint the background
*/
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 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;
}
/**
* 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};
myLocationView.setContentPadding(padding);
projection.invalidateContentPadding(padding);
invalidateFocalPointForTracking(myLocationView);
}
/**
* 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};
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 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;
}
/**
* 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);
}
/**
* 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;
}
/**
* 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);
}
/**
* 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);
}
public void setTilt(double tilt) {
myLocationView.setTilt(tilt);
}
public void setTilt(double tilt) {
myLocationView.setTilt(tilt);
}
private void invalidateFocalPointForTracking(MyLocationView myLocationView) {
if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) {
focalPointChangeListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
} else {
focalPointChangeListener.onFocalPointChanged(null);
}
private void invalidateFocalPointForTracking(MyLocationView myLocationView) {
if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) {
focalPointChangeListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
myLocationView.getCenterY()));
} else {
focalPointChangeListener.onFocalPointChanged(null);
}
}
}

View File

@@ -5,6 +5,6 @@ package com.mapbox.mapboxsdk.net;
*/
public interface ConnectivityListener {
void onNetworkStateChanged(boolean connected);
void onNetworkStateChanged(boolean connected);
}

View File

@@ -7,6 +7,7 @@ import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import timber.log.Timber;
import com.mapbox.mapboxsdk.MapboxAccountManager;
@@ -19,77 +20,77 @@ import java.util.concurrent.CopyOnWriteArrayList;
* Not public api.
*/
public class ConnectivityReceiver extends BroadcastReceiver {
private static ConnectivityReceiver INSTANCE;
private static ConnectivityReceiver INSTANCE;
/**
* Get or create the singleton instance
*/
public static synchronized ConnectivityReceiver instance(Context context) {
if (INSTANCE == null) {
//Register new instance
INSTANCE = new ConnectivityReceiver();
context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
/**
* Get or create the singleton instance
*/
public static synchronized ConnectivityReceiver instance(Context context) {
if (INSTANCE == null) {
//Register new instance
INSTANCE = new ConnectivityReceiver();
context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
//Add default listeners
INSTANCE.addListener(new NativeConnectivityListener());
}
return INSTANCE;
//Add default listeners
INSTANCE.addListener(new NativeConnectivityListener());
}
private List<ConnectivityListener> listeners = new CopyOnWriteArrayList<>();
return INSTANCE;
}
private ConnectivityReceiver() {
private List<ConnectivityListener> listeners = new CopyOnWriteArrayList<>();
private ConnectivityReceiver() {
}
/**
* @see BroadcastReceiver#onReceive(Context, Intent)
*/
@Override
public void onReceive(Context context, Intent intent) {
boolean connected = isConnected(context);
Timber.v("Connected: " + connected);
//Loop over listeners
for (ConnectivityListener listener : listeners) {
listener.onNetworkStateChanged(connected);
}
}
/**
* Add a listener to be notified
*
* @param listener the listener to add
*/
public void addListener(@NonNull ConnectivityListener listener) {
listeners.add(listener);
}
/**
* Remove a listener
*
* @param listener the listener to remove
*/
public void removeListener(@NonNull ConnectivityListener listener) {
listeners.remove(listener);
}
/**
* Get current connectivity state
*
* @param context current Context
* @return true if connected
*/
public boolean isConnected(Context context) {
Boolean connected = MapboxAccountManager.getInstance().isConnected();
if (connected != null) {
// Connectivity state overridden by app
return connected;
}
/**
* @see BroadcastReceiver#onReceive(Context, Intent)
*/
@Override
public void onReceive(Context context, Intent intent) {
boolean connected = isConnected(context);
Timber.v("Connected: " + connected);
//Loop over listeners
for (ConnectivityListener listener : listeners) {
listener.onNetworkStateChanged(connected);
}
}
/**
* Add a listener to be notified
*
* @param listener the listener to add
*/
public void addListener(@NonNull ConnectivityListener listener) {
listeners.add(listener);
}
/**
* Remove a listener
*
* @param listener the listener to remove
*/
public void removeListener(@NonNull ConnectivityListener listener) {
listeners.remove(listener);
}
/**
* Get current connectivity state
*
* @param context current Context
* @return true if connected
*/
public boolean isConnected(Context context) {
Boolean connected = MapboxAccountManager.getInstance().isConnected();
if (connected != null) {
// Connectivity state overridden by app
return connected;
}
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
}

View File

@@ -5,30 +5,30 @@ package com.mapbox.mapboxsdk.net;
*/
class NativeConnectivityListener implements ConnectivityListener {
static {
System.loadLibrary("mapbox-gl");
}
static {
System.loadLibrary("mapbox-gl");
}
private long nativePtr;
private boolean invalidated;
private long nativePtr;
private boolean invalidated;
NativeConnectivityListener(long nativePtr) {
this.nativePtr = nativePtr;
}
NativeConnectivityListener(long nativePtr) {
this.nativePtr = nativePtr;
}
NativeConnectivityListener() {
initialize();
}
NativeConnectivityListener() {
initialize();
}
@Override
public void onNetworkStateChanged(boolean connected) {
nativeOnConnectivityStateChanged(connected);
}
@Override
public void onNetworkStateChanged(boolean connected) {
nativeOnConnectivityStateChanged(connected);
}
protected native void nativeOnConnectivityStateChanged(boolean connected);
protected native void nativeOnConnectivityStateChanged(boolean connected);
protected native void initialize();
protected native void initialize();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -7,6 +7,7 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import timber.log.Timber;
import com.mapbox.mapboxsdk.MapboxAccountManager;
@@ -20,311 +21,310 @@ import java.io.File;
*/
public class OfflineManager {
//
// Static methods
//
//
// Static methods
//
static {
System.loadLibrary("mapbox-gl");
}
static {
System.loadLibrary("mapbox-gl");
}
// Default database name
private final static String DATABASE_NAME = "mbgl-offline.db";
// Default database name
private static final String DATABASE_NAME = "mbgl-offline.db";
/*
* The maximumCacheSize parameter is a limit applied to non-offline resources only,
* i.e. resources added to the database for the "ambient use" caching functionality.
* There is no size limit for offline resources.
/*
* The maximumCacheSize parameter is a limit applied to non-offline resources only,
* i.e. resources added to the database for the "ambient use" caching functionality.
* There is no size limit for offline resources.
*/
private static final long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
// Holds the pointer to JNI DefaultFileSource
private long mDefaultFileSourcePtr = 0;
// Makes sure callbacks come back to the main thread
private Handler handler;
// This object is implemented as a singleton
private static OfflineManager instance;
/**
* This callback receives an asynchronous response containing a list of all
* {@link OfflineRegion} in the database, or an error message otherwise.
*/
public interface ListOfflineRegionsCallback {
/**
* Receives the list of offline regions.
*
* @param offlineRegions the offline region array
*/
private final static long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
// Holds the pointer to JNI DefaultFileSource
private long mDefaultFileSourcePtr = 0;
// Makes sure callbacks come back to the main thread
private Handler handler;
// This object is implemented as a singleton
private static OfflineManager instance;
void onList(OfflineRegion[] offlineRegions);
/**
* This callback receives an asynchronous response containing a list of all
* {@link OfflineRegion} in the database, or an error message otherwise.
* Receives the error message.
*
* @param error the error message
*/
public interface ListOfflineRegionsCallback {
/**
* Receives the list of offline regions.
*
* @param offlineRegions the offline region array
*/
void onList(OfflineRegion[] offlineRegions);
void onError(String error);
}
/**
* Receives the error message.
*
* @param error the error message
*/
void onError(String error);
}
/**
* This callback receives an asynchronous response containing the newly created
* {@link OfflineRegion} in the database, or an error message otherwise.
*/
public interface CreateOfflineRegionCallback {
/**
* Receives the newly created offline region.
*
* @param offlineRegion the offline region to create
*/
void onCreate(OfflineRegion offlineRegion);
/**
* This callback receives an asynchronous response containing the newly created
* {@link OfflineRegion} in the database, or an error message otherwise.
* Receives the error message.
*
* @param error the error message to be shown
*/
public interface CreateOfflineRegionCallback {
/**
* Receives the newly created offline region.
*
* @param offlineRegion the offline region to create
*/
void onCreate(OfflineRegion offlineRegion);
void onError(String error);
}
/**
* Receives the error message.
*
* @param error the error message to be shown
*/
void onError(String error);
/*
* Constructors
*/
private OfflineManager(Context context) {
// Get a pointer to the DefaultFileSource instance
String assetRoot = getDatabasePath(context);
String cachePath = assetRoot + File.separator + DATABASE_NAME;
mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
if (MapboxAccountManager.getInstance() != null) {
setAccessToken(mDefaultFileSourcePtr, MapboxAccountManager.getInstance().getAccessToken());
}
/*
* Constructors
*/
// Delete any existing previous ambient cache database
deleteAmbientDatabase(context);
}
private OfflineManager(Context context) {
// Get a pointer to the DefaultFileSource instance
String assetRoot = getDatabasePath(context);
String cachePath = assetRoot + File.separator + DATABASE_NAME;
mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
public static String getDatabasePath(Context context) {
// Default value
boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
if (MapboxAccountManager.getInstance() != null) {
setAccessToken(mDefaultFileSourcePtr, MapboxAccountManager.getInstance().getAccessToken());
}
// Delete any existing previous ambient cache database
deleteAmbientDatabase(context);
try {
// Try getting a custom value from the app Manifest
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
context.getPackageName(), PackageManager.GET_META_DATA);
setStorageExternal = appInfo.metaData.getBoolean(
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
} catch (PackageManager.NameNotFoundException nameNotFoundException) {
Timber.e("Failed to read the package metadata: " + nameNotFoundException.getMessage());
} catch (Exception exception) {
Timber.e("Failed to read the storage key: " + exception.getMessage());
}
public static String getDatabasePath(Context context) {
// Default value
boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
String databasePath = null;
if (setStorageExternal && isExternalStorageReadable()) {
try {
// Try getting the external storage path
databasePath = context.getExternalFilesDir(null).getAbsolutePath();
} catch (NullPointerException nullPointerException) {
Timber.e("Failed to obtain the external storage path: " + nullPointerException.getMessage());
}
}
if (databasePath == null) {
// Default to internal storage
databasePath = context.getFilesDir().getAbsolutePath();
}
return databasePath;
}
/**
* Checks if external storage is available to at least read. In order for this to work, make
* sure you include &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
* (or WRITE_EXTERNAL_STORAGE) for API level &lt; 18 in your app Manifest.
* <p>
* Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
* </p>
*
* @return true if external storage is readable
*/
public static boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
Timber.w("External storage was requested but it isn't readable. For API level < 18"
+ " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
+ " permissions in your app Manifest (defaulting to internal storage).");
return false;
}
private void deleteAmbientDatabase(final Context context) {
// Delete the file in a separate thread to avoid affecting the UI
new Thread(new Runnable() {
@Override
public void run() {
try {
// Try getting a custom value from the app Manifest
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
context.getPackageName(), PackageManager.GET_META_DATA);
setStorageExternal = appInfo.metaData.getBoolean(
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
} catch (PackageManager.NameNotFoundException e) {
Timber.e("Failed to read the package metadata: " + e.getMessage());
} catch (Exception e) {
Timber.e("Failed to read the storage key: " + e.getMessage());
String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db";
File file = new File(path);
if (file.exists()) {
file.delete();
Timber.d("Old ambient cache database deleted to save space: " + path);
}
} catch (Exception exception) {
Timber.e("Failed to delete old ambient cache database: " + exception.getMessage());
}
}
}).start();
}
String databasePath = null;
if (setStorageExternal && isExternalStorageReadable()) {
try {
// Try getting the external storage path
databasePath = context.getExternalFilesDir(null).getAbsolutePath();
} catch (NullPointerException e) {
Timber.e("Failed to obtain the external storage path: " + e.getMessage());
}
}
public static synchronized OfflineManager getInstance(Context context) {
if (instance == null) {
instance = new OfflineManager(context);
}
return instance;
}
if (databasePath == null) {
// Default to internal storage
databasePath = context.getFilesDir().getAbsolutePath();
}
/**
* Access token getter/setter
*
* @param accessToken the accessToken to be used by the offline manager.
* @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#start(Context, String)} ()}
*/
@Deprecated
public void setAccessToken(String accessToken) {
setAccessToken(mDefaultFileSourcePtr, accessToken);
}
return databasePath;
/**
* Get Access Token
*
* @return Access Token
* @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()}
*/
@Deprecated
public String getAccessToken() {
return getAccessToken(mDefaultFileSourcePtr);
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
/**
* Checks if external storage is available to at least read. In order for this to work, make
* sure you include &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
* (or WRITE_EXTERNAL_STORAGE) for API level &lt; 18 in your app Manifest.
* <p>
* Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
* </p>
*
* @return true if external storage is readable
*/
public static boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return handler;
}
Timber.w("External storage was requested but it isn't readable. For API level < 18"
+ " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
+ " permissions in your app Manifest (defaulting to internal storage).");
return false;
}
private void deleteAmbientDatabase(final Context context) {
// Delete the file in a separate thread to avoid affecting the UI
new Thread(new Runnable() {
@Override
public void run() {
try {
String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db";
File file = new File(path);
if (file.exists()) {
file.delete();
Timber.d("Old ambient cache database deleted to save space: " + path);
}
} catch (Exception e) {
Timber.e("Failed to delete old ambient cache database: " + e.getMessage());
}
}
}).start();
}
public static synchronized OfflineManager getInstance(Context context) {
if (instance == null) {
instance = new OfflineManager(context);
}
return instance;
}
/**
* Access token getter/setter
*
* @param accessToken the accessToken to be used by the offline manager.
* @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#start(Context, String)} ()}
*/
@Deprecated
public void setAccessToken(String accessToken) {
setAccessToken(mDefaultFileSourcePtr, accessToken);
}
/**
* Get Access Token
*
* @return Access Token
* @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()}
*/
@Deprecated
public String getAccessToken() {
return getAccessToken(mDefaultFileSourcePtr);
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
return handler;
}
/**
* Retrieve all regions in the offline database.
* <p>
* The query will be executed asynchronously and the results passed to the given
* callback on the main thread.
* </p>
*
* @param callback the callback to be invoked
*/
public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) {
listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() {
@Override
public void onList(final OfflineRegion[] offlineRegions) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onList(offlineRegions);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
/**
* Retrieve all regions in the offline database.
* <p>
* The query will be executed asynchronously and the results passed to the given
* callback on the main thread.
* </p>
*
* @param callback the callback to be invoked
*/
public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) {
listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() {
@Override
public void onList(final OfflineRegion[] offlineRegions) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onList(offlineRegions);
}
});
}
}
/**
* Create an offline region in the database.
* <p>
* When the initial database queries have completed, the provided callback will be
* executed on the main thread.
* </p>
* <p>
* Note that the resulting region will be in an inactive download state; to begin
* downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`,
* optionally registering an `OfflineRegionObserver` beforehand.
* </p>
*
* @param definition the offline region definition
* @param metadata the metadata in bytes
* @param callback the callback to be invoked
*/
public void createOfflineRegion(
@NonNull OfflineRegionDefinition definition,
@NonNull byte[] metadata,
@NonNull final CreateOfflineRegionCallback callback) {
createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() {
@Override
public void onCreate(final OfflineRegion offlineRegion) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onCreate(offlineRegion);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
}
});
}
/*
* Changing or bypassing this limit without permission from Mapbox is prohibited
* by the Mapbox Terms of Service.
*/
public void setOfflineMapboxTileCountLimit(long limit) {
setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit);
}
/**
* Create an offline region in the database.
* <p>
* When the initial database queries have completed, the provided callback will be
* executed on the main thread.
* </p>
* <p>
* Note that the resulting region will be in an inactive download state; to begin
* downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`,
* optionally registering an `OfflineRegionObserver` beforehand.
* </p>
*
* @param definition the offline region definition
* @param metadata the metadata in bytes
* @param callback the callback to be invoked
*/
public void createOfflineRegion(
@NonNull OfflineRegionDefinition definition,
@NonNull byte[] metadata,
@NonNull final CreateOfflineRegionCallback callback) {
createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() {
@Override
public void onCreate(final OfflineRegion offlineRegion) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onCreate(offlineRegion);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
/*
* Changing or bypassing this limit without permission from Mapbox is prohibited
* by the Mapbox Terms of Service.
*/
public void setOfflineMapboxTileCountLimit(long limit) {
setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit);
}
/*
* Native methods
*/
/*
* Native methods
*/
private native long createDefaultFileSource(
String cachePath, String assetRoot, long maximumCacheSize);
private native long createDefaultFileSource(
String cachePath, String assetRoot, long maximumCacheSize);
private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
private native String getAccessToken(long defaultFileSourcePtr);
private native String getAccessToken(long defaultFileSourcePtr);
private native void listOfflineRegions(
long defaultFileSourcePtr, ListOfflineRegionsCallback callback);
private native void listOfflineRegions(
long defaultFileSourcePtr, ListOfflineRegionsCallback callback);
private native void createOfflineRegion(
long defaultFileSourcePtr, OfflineRegionDefinition definition,
byte[] metadata, CreateOfflineRegionCallback callback);
private native void createOfflineRegion(
long defaultFileSourcePtr, OfflineRegionDefinition definition,
byte[] metadata, CreateOfflineRegionCallback callback);
private native void setOfflineMapboxTileCountLimit(
long defaultFileSourcePtr, long limit);
private native void setOfflineMapboxTileCountLimit(
long defaultFileSourcePtr, long limit);
}

View File

@@ -4,6 +4,7 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import timber.log.Timber;
import java.lang.annotation.Retention;
@@ -16,414 +17,418 @@ import java.lang.annotation.RetentionPolicy;
*/
public class OfflineRegion {
//
// Static methods
//
//
// Static methods
//
static {
System.loadLibrary("mapbox-gl");
}
static {
System.loadLibrary("mapbox-gl");
}
// Parent OfflineManager
private OfflineManager offlineManager;
// Parent OfflineManager
private OfflineManager offlineManager;
// Members
private long mId = 0;
private OfflineRegionDefinition mDefinition = null;
// Members
private long mId = 0;
private OfflineRegionDefinition mDefinition = null;
/**
* Arbitrary binary region metadata. The contents are opaque to the SDK implementation;
* it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp
* for a sample implementation that uses JSON to store an offline region name.
*/
private byte[] mMetadata = null;
// Holds the pointer to JNI OfflineRegion
private long mOfflineRegionPtr = 0;
// Makes sure callbacks come back to the main thread
private Handler handler;
/**
* A region can have a single observer, which gets notified whenever a change
* to the region's status occurs.
*/
public interface OfflineRegionObserver {
/**
* Arbitrary binary region metadata. The contents are opaque to the SDK implementation;
* it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp
* for a sample implementation that uses JSON to store an offline region name.
*/
private byte[] mMetadata = null;
// Holds the pointer to JNI OfflineRegion
private long mOfflineRegionPtr = 0;
// Makes sure callbacks come back to the main thread
private Handler handler;
/**
* A region can have a single observer, which gets notified whenever a change
* to the region's status occurs.
*/
public interface OfflineRegionObserver {
/**
* Implement this method to be notified of a change in the status of an
* offline region. Status changes include any change in state of the members
* of OfflineRegionStatus.
* <p>
* This method will be executed on the main thread.
* </p>
*
* @param status the changed status
*/
void onStatusChanged(OfflineRegionStatus status);
/**
* Implement this method to be notified of errors encountered while downloading
* regional resources. Such errors may be recoverable; for example the implementation
* will attempt to re-request failed resources based on an exponential backoff
* algorithm, or when it detects that network access has been restored.
* <p>
* This method will be executed on the main thread.
* </p>
*
* @param error the offline region error message
*/
void onError(OfflineRegionError error);
/*
* Implement this method to be notified when the limit on the number of Mapbox
* tiles stored for offline regions has been reached.
*
* Once the limit has been reached, the SDK will not download further offline
* tiles from Mapbox APIs until existing tiles have been removed. Contact your
* Mapbox sales representative to raise the limit.
*
* This limit does not apply to non-Mapbox tile sources.
*
* This method will be executed on the main thread.
*/
void mapboxTileCountLimitExceeded(long limit);
}
/**
* This callback receives an asynchronous response containing the {@link OfflineRegionStatus}
* of the offline region, or a {@link String} error message otherwise.
*/
public interface OfflineRegionStatusCallback {
/**
* Receives the status
*
* @param status the offline region status
*/
void onStatus(OfflineRegionStatus status);
/**
* Receives the error message
*
* @param error the error message
*/
void onError(String error);
}
/**
* This callback receives an asynchronous response containing a notification when
* an offline region has been deleted, or a {@link String} error message otherwise.
*/
public interface OfflineRegionDeleteCallback {
/**
* Receives the delete notification
*/
void onDelete();
/**
* Receives the error message
*
* @param error the error message
*/
void onError(String error);
}
/**
* This callback receives an asynchronous response containing the newly update
* OfflineMetadata in the database, or an error message otherwise.
*/
public interface OfflineRegionUpdateMetadataCallback {
/**
* Receives the newly update offline region metadata.
*
* @param metadata the offline metadata to u[date
*/
void onUpdate(byte[] metadata);
/**
* Receives the error message.
*
* @param error the error message to be shown
*/
void onError(String error);
}
/**
* A region is either inactive (not downloading, but previously-downloaded
* resources are available for use), or active (resources are being downloaded
* or will be downloaded, if necessary, when network access is available).
* Implement this method to be notified of a change in the status of an
* offline region. Status changes include any change in state of the members
* of OfflineRegionStatus.
* <p>
* This state is independent of whether or not the complete set of resources
* is currently available for offline use. To check if that is the case, use
* `OfflineRegionStatus.isComplete()`.
* This method will be executed on the main thread.
* </p>
*
* @param status the changed status
*/
@IntDef({STATE_INACTIVE, STATE_ACTIVE})
@Retention(RetentionPolicy.SOURCE)
public @interface DownloadState {
}
public static final int STATE_INACTIVE = 0;
public static final int STATE_ACTIVE = 1;
// Keep track of the region state
private int state = STATE_INACTIVE;
private boolean deliverInactiveMessages = false;
void onStatusChanged(OfflineRegionStatus status);
/**
* Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if
* the region state has been set as STATE_INACTIVE.
* Implement this method to be notified of errors encountered while downloading
* regional resources. Such errors may be recoverable; for example the implementation
* will attempt to re-request failed resources based on an exponential backoff
* algorithm, or when it detects that network access has been restored.
* <p>
* This method will be executed on the main thread.
* </p>
*
* @return true if delivering inactive messages
* @param error the offline region error message
*/
public boolean isDeliveringInactiveMessages() {
return deliverInactiveMessages;
}
void onError(OfflineRegionError error);
/*
* Implement this method to be notified when the limit on the number of Mapbox
* tiles stored for offline regions has been reached.
*
* Once the limit has been reached, the SDK will not download further offline
* tiles from Mapbox APIs until existing tiles have been removed. Contact your
* Mapbox sales representative to raise the limit.
*
* This limit does not apply to non-Mapbox tile sources.
*
* This method will be executed on the main thread.
*/
void mapboxTileCountLimitExceeded(long limit);
}
/**
* This callback receives an asynchronous response containing the {@link OfflineRegionStatus}
* of the offline region, or a {@link String} error message otherwise.
*/
public interface OfflineRegionStatusCallback {
/**
* Receives the status
*
* @param status the offline region status
*/
void onStatus(OfflineRegionStatus status);
/**
* When set true, the `OfflineRegionObserver` will continue to deliver messages even if
* the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set
* false, the client won't be notified of further messages.
* Receives the error message
*
* @param deliverInactiveMessages true if it should deliver inactive messages
* @param error the error message
*/
public void setDeliverInactiveMessages(boolean deliverInactiveMessages) {
this.deliverInactiveMessages = deliverInactiveMessages;
}
void onError(String error);
}
private boolean deliverMessages() {
if (state == STATE_ACTIVE) return true;
if (isDeliveringInactiveMessages()) return true;
return false;
}
/*
* Constructor
/**
* This callback receives an asynchronous response containing a notification when
* an offline region has been deleted, or a {@link String} error message otherwise.
*/
public interface OfflineRegionDeleteCallback {
/**
* Receives the delete notification
*/
void onDelete();
private OfflineRegion() {
// For JNI use only, to create a new offline region, use
// OfflineManager.createOfflineRegion() instead.
}
/*
* Getters
/**
* Receives the error message
*
* @param error the error message
*/
void onError(String error);
}
public long getID() {
return mId;
/**
* This callback receives an asynchronous response containing the newly update
* OfflineMetadata in the database, or an error message otherwise.
*/
public interface OfflineRegionUpdateMetadataCallback {
/**
* Receives the newly update offline region metadata.
*
* @param metadata the offline metadata to u[date
*/
void onUpdate(byte[] metadata);
/**
* Receives the error message.
*
* @param error the error message to be shown
*/
void onError(String error);
}
/**
* A region is either inactive (not downloading, but previously-downloaded
* resources are available for use), or active (resources are being downloaded
* or will be downloaded, if necessary, when network access is available).
* <p>
* This state is independent of whether or not the complete set of resources
* is currently available for offline use. To check if that is the case, use
* `OfflineRegionStatus.isComplete()`.
* </p>
*/
@IntDef( {STATE_INACTIVE, STATE_ACTIVE})
@Retention(RetentionPolicy.SOURCE)
public @interface DownloadState {
}
public static final int STATE_INACTIVE = 0;
public static final int STATE_ACTIVE = 1;
// Keep track of the region state
private int state = STATE_INACTIVE;
private boolean deliverInactiveMessages = false;
/**
* Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if
* the region state has been set as STATE_INACTIVE.
*
* @return true if delivering inactive messages
*/
public boolean isDeliveringInactiveMessages() {
return deliverInactiveMessages;
}
/**
* When set true, the `OfflineRegionObserver` will continue to deliver messages even if
* the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set
* false, the client won't be notified of further messages.
*
* @param deliverInactiveMessages true if it should deliver inactive messages
*/
public void setDeliverInactiveMessages(boolean deliverInactiveMessages) {
this.deliverInactiveMessages = deliverInactiveMessages;
}
private boolean deliverMessages() {
if (state == STATE_ACTIVE) {
return true;
}
if (isDeliveringInactiveMessages()) {
return true;
}
return false;
}
/*
* Constructor
*/
private OfflineRegion() {
// For JNI use only, to create a new offline region, use
// OfflineManager.createOfflineRegion() instead.
}
/*
* Getters
*/
public long getID() {
return mId;
}
public OfflineRegionDefinition getDefinition() {
return mDefinition;
}
public byte[] getMetadata() {
return mMetadata;
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
public OfflineRegionDefinition getDefinition() {
return mDefinition;
}
return handler;
}
public byte[] getMetadata() {
return mMetadata;
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
/**
* Register an observer to be notified when the state of the region changes.
*
* @param observer the observer to be notified
*/
public void setObserver(@NonNull final OfflineRegionObserver observer) {
setOfflineRegionObserver(new OfflineRegionObserver() {
@Override
public void onStatusChanged(final OfflineRegionStatus status) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void run() {
observer.onStatusChanged(status);
}
});
}
}
return handler;
}
/**
* Register an observer to be notified when the state of the region changes.
*
* @param observer the observer to be notified
*/
public void setObserver(@NonNull final OfflineRegionObserver observer) {
setOfflineRegionObserver(new OfflineRegionObserver() {
@Override
public void onError(final OfflineRegionError error) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void onStatusChanged(final OfflineRegionStatus status) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void run() {
observer.onStatusChanged(status);
}
});
}
public void run() {
observer.onError(error);
}
@Override
public void onError(final OfflineRegionError error) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void run() {
observer.onError(error);
}
});
}
}
@Override
public void mapboxTileCountLimitExceeded(final long limit) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void run() {
observer.mapboxTileCountLimitExceeded(limit);
}
});
}
}
});
}
/**
* Pause or resume downloading of regional resources.
*
* @param state the download state
*/
public void setDownloadState(@DownloadState int state) {
this.state = state;
setOfflineRegionDownloadState(state);
}
/**
* Retrieve the current status of the region. The query will be executed
* asynchronously and the results passed to the given callback which will be
* executed on the main thread.
*
* @param callback the callback to invoked.
*/
public void getStatus(@NonNull final OfflineRegionStatusCallback callback) {
getOfflineRegionStatus(new OfflineRegionStatusCallback() {
@Override
public void onStatus(final OfflineRegionStatus status) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onStatus(status);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
/**
* Remove an offline region from the database and perform any resources evictions
* necessary as a result.
* <p>
* Eviction works by removing the least-recently requested resources not also required
* by other regions, until the database shrinks below a certain size.
* </p>
* <p>
* When the operation is complete or encounters an error, the given callback will be
* executed on the main thread.
* </p>
* <p>
* After you call this method, you may not call any additional methods on this object.
* </p>
*
* @param callback the callback to be invoked
*/
public void delete(@NonNull final OfflineRegionDeleteCallback callback) {
deleteOfflineRegion(new OfflineRegionDeleteCallback() {
@Override
public void onDelete() {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onDelete();
OfflineRegion.this.finalize();
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
/**
* Update an offline region metadata from the database.
* <p>
* When the operation is complete or encounters an error, the given callback will be
* executed on the main thread.
* </p>
* <p>
* After you call this method, you may not call any additional methods on this object.
* </p>
*
* @param callback the callback to be invoked
*/
public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) {
updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() {
@Override
public void onUpdate(final byte[] metadata) {
getHandler().post(new Runnable() {
@Override
public void run() {
mMetadata = metadata;
callback.onUpdate(metadata);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
@Override
protected void finalize() {
try {
super.finalize();
destroyOfflineRegion();
} catch (Throwable throwable) {
Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage());
});
}
}
@Override
public void mapboxTileCountLimitExceeded(final long limit) {
if (deliverMessages()) {
getHandler().post(new Runnable() {
@Override
public void run() {
observer.mapboxTileCountLimitExceeded(limit);
}
});
}
}
});
}
/**
* Pause or resume downloading of regional resources.
*
* @param state the download state
*/
public void setDownloadState(@DownloadState int state) {
this.state = state;
setOfflineRegionDownloadState(state);
}
/**
* Retrieve the current status of the region. The query will be executed
* asynchronously and the results passed to the given callback which will be
* executed on the main thread.
*
* @param callback the callback to invoked.
*/
public void getStatus(@NonNull final OfflineRegionStatusCallback callback) {
getOfflineRegionStatus(new OfflineRegionStatusCallback() {
@Override
public void onStatus(final OfflineRegionStatus status) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onStatus(status);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
/**
* Remove an offline region from the database and perform any resources evictions
* necessary as a result.
* <p>
* Eviction works by removing the least-recently requested resources not also required
* by other regions, until the database shrinks below a certain size.
* </p>
* <p>
* When the operation is complete or encounters an error, the given callback will be
* executed on the main thread.
* </p>
* <p>
* After you call this method, you may not call any additional methods on this object.
* </p>
*
* @param callback the callback to be invoked
*/
public void delete(@NonNull final OfflineRegionDeleteCallback callback) {
deleteOfflineRegion(new OfflineRegionDeleteCallback() {
@Override
public void onDelete() {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onDelete();
OfflineRegion.this.finalize();
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
/**
* Update an offline region metadata from the database.
* <p>
* When the operation is complete or encounters an error, the given callback will be
* executed on the main thread.
* </p>
* <p>
* After you call this method, you may not call any additional methods on this object.
* </p>
*
* @param callback the callback to be invoked
*/
public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) {
updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() {
@Override
public void onUpdate(final byte[] metadata) {
getHandler().post(new Runnable() {
@Override
public void run() {
mMetadata = metadata;
callback.onUpdate(metadata);
}
});
}
@Override
public void onError(final String error) {
getHandler().post(new Runnable() {
@Override
public void run() {
callback.onError(error);
}
});
}
});
}
@Override
protected void finalize() {
try {
super.finalize();
destroyOfflineRegion();
} catch (Throwable throwable) {
Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage());
}
}
/*
* Native methods
*/
/*
* Native methods
*/
private native void destroyOfflineRegion();
private native void destroyOfflineRegion();
private native void setOfflineRegionObserver(
OfflineRegionObserver observerCallback);
private native void setOfflineRegionObserver(
OfflineRegionObserver observerCallback);
private native void setOfflineRegionDownloadState(
@DownloadState int offlineRegionDownloadState);
private native void setOfflineRegionDownloadState(
@DownloadState int offlineRegionDownloadState);
private native void getOfflineRegionStatus(
OfflineRegionStatusCallback statusCallback);
private native void getOfflineRegionStatus(
OfflineRegionStatusCallback statusCallback);
private native void deleteOfflineRegion(
OfflineRegionDeleteCallback deleteCallback);
private native void deleteOfflineRegion(
OfflineRegionDeleteCallback deleteCallback);
private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback);
private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback);
}

View File

@@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.offline;
/**
* This is the interface that all Offline Region definitions have to implement.
*
* <p>
* For the present, a tile pyramid is the only type of offline region.
*/
public interface OfflineRegionDefinition {

View File

@@ -10,44 +10,47 @@ import java.lang.annotation.RetentionPolicy;
*/
public class OfflineRegionError {
/**
* Error code, as a string, self-explanatory.
*/
@StringDef({REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER})
@Retention(RetentionPolicy.SOURCE)
public @interface ErrorReason {}
/**
* Error code, as a string, self-explanatory.
*/
@StringDef( {REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER})
@Retention(RetentionPolicy.SOURCE)
public @interface ErrorReason {
}
public static final String REASON_SUCCESS = "REASON_SUCCESS";
public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND";
public static final String REASON_SERVER = "REASON_SERVER";
public static final String REASON_CONNECTION = "REASON_CONNECTION";
public static final String REASON_OTHER = "REASON_OTHER";
public static final String REASON_SUCCESS = "REASON_SUCCESS";
public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND";
public static final String REASON_SERVER = "REASON_SERVER";
public static final String REASON_CONNECTION = "REASON_CONNECTION";
public static final String REASON_OTHER = "REASON_OTHER";
private @ErrorReason String reason;
@ErrorReason
private String reason;
/**
/* An error message from the request handler, e.g. a server message or a system message
/* informing the user about the reason for the failure.
*/
private String message;
/**
* /* An error message from the request handler, e.g. a server message or a system message
* /* informing the user about the reason for the failure.
*/
private String message;
/*
* Constructors
*/
/*
* Constructors
*/
private OfflineRegionError() {
// For JNI use only
}
private OfflineRegionError() {
// For JNI use only
}
/*
* Getters
*/
/*
* Getters
*/
public @ErrorReason String getReason() {
return reason;
}
@ErrorReason
public String getReason() {
return reason;
}
public String getMessage() {
return message;
}
public String getMessage() {
return message;
}
}

View File

@@ -4,101 +4,103 @@ package com.mapbox.mapboxsdk.offline;
* A region's status includes its active/inactive state as well as counts
* of the number of resources that have completed downloading, their total
* size in bytes, and the total number of resources that are required.
*
* <p>
* Note that the total required size in bytes is not currently available. A
* future API release may provide an estimate of this number.
*/
public class OfflineRegionStatus {
@OfflineRegion.DownloadState private int downloadState = OfflineRegion.STATE_INACTIVE;
@OfflineRegion.DownloadState
private int downloadState = OfflineRegion.STATE_INACTIVE;
/**
* The number of resources (inclusive of tiles) that have been fully downloaded
* and are ready for offline access.
*/
private long completedResourceCount = 0;
/**
* The number of resources (inclusive of tiles) that have been fully downloaded
* and are ready for offline access.
*/
private long completedResourceCount = 0;
/**
* The cumulative size, in bytes, of all resources (inclusive of tiles) that have
* been fully downloaded.
*/
private long completedResourceSize = 0;
/**
* The cumulative size, in bytes, of all resources (inclusive of tiles) that have
* been fully downloaded.
*/
private long completedResourceSize = 0;
/**
* The number of tiles that have been fully downloaded and are ready for
* offline access.
*/
private long completedTileCount = 0;
/**
* The number of tiles that have been fully downloaded and are ready for
* offline access.
*/
private long completedTileCount = 0;
/**
* The cumulative size, in bytes, of all tiles that have been fully downloaded.
*/
private long completedTileSize = 0;
/**
* The cumulative size, in bytes, of all tiles that have been fully downloaded.
*/
private long completedTileSize = 0;
/**
* The number of resources that are known to be required for this region. See the
* documentation for `requiredResourceCountIsPrecise` for an important caveat
* about this number.
*/
private long requiredResourceCount = 0;
/**
* The number of resources that are known to be required for this region. See the
* documentation for `requiredResourceCountIsPrecise` for an important caveat
* about this number.
*/
private long requiredResourceCount = 0;
/**
* This property is true when the value of requiredResourceCount is a precise
* count of the number of required resources, and false when it is merely a lower
* bound.
*
* Specifically, it is false during early phases of an offline download. Once
* style and tile sources have been downloaded, it is possible to calculate the
* precise number of required resources, at which point it is set to true.
*/
private boolean requiredResourceCountIsPrecise = true;
/**
* This property is true when the value of requiredResourceCount is a precise
* count of the number of required resources, and false when it is merely a lower
* bound.
* <p>
* Specifically, it is false during early phases of an offline download. Once
* style and tile sources have been downloaded, it is possible to calculate the
* precise number of required resources, at which point it is set to true.
*/
private boolean requiredResourceCountIsPrecise = true;
/*
* Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object.
*/
/*
* Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object.
*/
private OfflineRegionStatus() {
// For JNI use only
}
private OfflineRegionStatus() {
// For JNI use only
}
/*
* Is the region complete?
*/
/*
* Is the region complete?
*/
public boolean isComplete() {
return (completedResourceCount == requiredResourceCount);
}
public boolean isComplete() {
return (completedResourceCount == requiredResourceCount);
}
/*
* Getters
*/
/*
* Getters
*/
public @OfflineRegion.DownloadState int getDownloadState() {
return downloadState;
}
@OfflineRegion.DownloadState
public int getDownloadState() {
return downloadState;
}
public long getCompletedResourceCount() {
return completedResourceCount;
}
public long getCompletedResourceCount() {
return completedResourceCount;
}
public long getCompletedResourceSize() {
return completedResourceSize;
}
public long getCompletedResourceSize() {
return completedResourceSize;
}
public long getCompletedTileCount() {
return completedTileCount;
}
public long getCompletedTileCount() {
return completedTileCount;
}
public long getCompletedTileSize() {
return completedTileSize;
}
public long getCompletedTileSize() {
return completedTileSize;
}
public long getRequiredResourceCount() {
return requiredResourceCount;
}
public long getRequiredResourceCount() {
return requiredResourceCount;
}
public boolean isRequiredResourceCountPrecise() {
return requiredResourceCountIsPrecise;
}
public boolean isRequiredResourceCountPrecise() {
return requiredResourceCountIsPrecise;
}
}

View File

@@ -5,61 +5,61 @@ 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.
*
* <p>
* maxZoom may be ∞, 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.
*/
public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefinition {
private String styleURL;
private LatLngBounds bounds;
private double minZoom;
private double maxZoom;
private float pixelRatio;
private String styleURL;
private LatLngBounds bounds;
private double minZoom;
private double maxZoom;
private float pixelRatio;
/*
* Constructors
*/
/*
* Constructors
*/
private OfflineTilePyramidRegionDefinition() {
// For JNI use only
}
private OfflineTilePyramidRegionDefinition() {
// For JNI use only
}
public OfflineTilePyramidRegionDefinition(
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
this.styleURL = styleURL;
this.bounds = bounds;
this.minZoom = minZoom;
this.maxZoom = maxZoom;
this.pixelRatio = pixelRatio;
}
public OfflineTilePyramidRegionDefinition(
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
this.styleURL = styleURL;
this.bounds = bounds;
this.minZoom = minZoom;
this.maxZoom = maxZoom;
this.pixelRatio = pixelRatio;
}
/*
* Getters
*/
/*
* Getters
*/
public String getStyleURL() {
return styleURL;
}
public String getStyleURL() {
return styleURL;
}
public LatLngBounds getBounds() {
return bounds;
}
public LatLngBounds getBounds() {
return bounds;
}
public double getMinZoom() {
return minZoom;
}
public double getMinZoom() {
return minZoom;
}
public double getMaxZoom() {
return maxZoom;
}
public double getMaxZoom() {
return maxZoom;
}
public float getPixelRatio() {
return pixelRatio;
}
public float getPixelRatio() {
return pixelRatio;
}
}

View File

@@ -1,12 +1,11 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.UiThread;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* The background color or pattern of the map.
@@ -16,93 +15,94 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
@UiThread
public class BackgroundLayer extends Layer {
/**
* Creates a BackgroundLayer.
*
* @param nativePtr pointer used by core
*/
public BackgroundLayer(long nativePtr) {
super(nativePtr);
/**
* Creates a BackgroundLayer.
*
* @param nativePtr pointer used by core
*/
public BackgroundLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a BackgroundLayer.
*
* @param layerId the id of the layer
*/
public BackgroundLayer(String layerId) {
initialize(layerId);
}
protected native void initialize(String layerId);
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public BackgroundLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
/**
* Get the BackgroundColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getBackgroundColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundColor());
}
/**
* The color with which the background will be drawn.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getBackgroundColorAsInt() {
PropertyValue<String> value = getBackgroundColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("background-color was set as a Function");
}
/**
* Creates a BackgroundLayer.
*
* @param layerId the id of the layer
*/
public BackgroundLayer(String layerId) {
initialize(layerId);
}
protected native void initialize(String layerId);
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public BackgroundLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
/**
* Get the BackgroundColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getBackgroundColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundColor());
}
/**
* The color with which the background will be drawn.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getBackgroundColorAsInt() {
PropertyValue<String> value = getBackgroundColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("background-color was set as a Function");
}
}
/**
* Get the BackgroundPattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getBackgroundPattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundPattern());
}
/**
* Get the BackgroundOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getBackgroundOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetBackgroundOpacity());
}
private native Object nativeGetBackgroundColor();
private native Object nativeGetBackgroundPattern();
private native Object nativeGetBackgroundOpacity();
}
@Override
protected native void finalize() throws Throwable;
/**
* Get the BackgroundPattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getBackgroundPattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundPattern());
}
/**
* Get the BackgroundOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getBackgroundOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetBackgroundOpacity());
}
private native Object nativeGetBackgroundColor();
private native Object nativeGetBackgroundPattern();
private native Object nativeGetBackgroundOpacity();
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -5,8 +5,8 @@ package com.mapbox.mapboxsdk.style.layers;
*/
public class CannotAddLayerException extends RuntimeException {
public CannotAddLayerException(String message) {
super(message);
}
public CannotAddLayerException(String message) {
super(message);
}
}

View File

@@ -1,12 +1,11 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.UiThread;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A filled circle.
@@ -16,254 +15,257 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
@UiThread
public class CircleLayer extends Layer {
/**
* Creates a CircleLayer.
*
* @param nativePtr pointer used by core
*/
public CircleLayer(long nativePtr) {
super(nativePtr);
/**
* Creates a CircleLayer.
*
* @param nativePtr pointer used by core
*/
public CircleLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a CircleLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public CircleLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public CircleLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public CircleLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public CircleLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public CircleLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
/**
* Get the CircleRadius property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleRadius() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleRadius());
}
/**
* Get the CircleColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleColor());
}
/**
* The fill color of the circle.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getCircleColorAsInt() {
PropertyValue<String> value = getCircleColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("circle-color was set as a Function");
}
}
/**
* Creates a CircleLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public CircleLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public CircleLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public CircleLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public CircleLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
/**
* Get the CircleBlur property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleBlur() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleBlur());
}
/**
* Get the CircleOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleOpacity());
}
/**
* Get the CircleTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getCircleTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetCircleTranslate());
}
/**
* Get the CircleTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleTranslateAnchor());
}
/**
* Get the CirclePitchScale property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCirclePitchScale() {
return (PropertyValue<String>) new PropertyValue(nativeGetCirclePitchScale());
}
/**
* Get the CircleStrokeWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleStrokeWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeWidth());
}
/**
* Get the CircleStrokeColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleStrokeColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleStrokeColor());
}
/**
* The stroke color of the circle.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getCircleStrokeColorAsInt() {
PropertyValue<String> value = getCircleStrokeColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("circle-stroke-color was set as a Function");
}
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public CircleLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
/**
* Get the CircleStrokeOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleStrokeOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeOpacity());
}
// Property getters
private native Object nativeGetCircleRadius();
/**
* Get the CircleRadius property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleRadius() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleRadius());
}
/**
* Get the CircleColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleColor());
}
/**
* The fill color of the circle.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getCircleColorAsInt() {
PropertyValue<String> value = getCircleColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("circle-color was set as a Function");
}
}
private native Object nativeGetCircleColor();
/**
* Get the CircleBlur property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleBlur() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleBlur());
}
/**
* Get the CircleOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleOpacity());
}
/**
* Get the CircleTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getCircleTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetCircleTranslate());
}
/**
* Get the CircleTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleTranslateAnchor());
}
/**
* Get the CirclePitchScale property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCirclePitchScale() {
return (PropertyValue<String>) new PropertyValue(nativeGetCirclePitchScale());
}
/**
* Get the CircleStrokeWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleStrokeWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeWidth());
}
/**
* Get the CircleStrokeColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCircleStrokeColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetCircleStrokeColor());
}
/**
* The stroke color of the circle.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getCircleStrokeColorAsInt() {
PropertyValue<String> value = getCircleStrokeColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("circle-stroke-color was set as a Function");
}
}
private native Object nativeGetCircleBlur();
/**
* Get the CircleStrokeOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getCircleStrokeOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeOpacity());
}
private native Object nativeGetCircleRadius();
private native Object nativeGetCircleOpacity();
private native Object nativeGetCircleColor();
private native Object nativeGetCircleTranslate();
private native Object nativeGetCircleBlur();
private native Object nativeGetCircleTranslateAnchor();
private native Object nativeGetCircleOpacity();
private native Object nativeGetCirclePitchScale();
private native Object nativeGetCircleTranslate();
private native Object nativeGetCircleStrokeWidth();
private native Object nativeGetCircleTranslateAnchor();
private native Object nativeGetCircleStrokeColor();
private native Object nativeGetCirclePitchScale();
private native Object nativeGetCircleStrokeWidth();
private native Object nativeGetCircleStrokeColor();
private native Object nativeGetCircleStrokeOpacity();
private native Object nativeGetCircleStrokeOpacity();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -8,27 +8,28 @@ package com.mapbox.mapboxsdk.style.layers;
*/
public class CustomLayer extends Layer {
public CustomLayer(String id,
long context,
long initializeFunction,
long renderFunction,
long deinitializeFunction) {
initialize(id, initializeFunction, renderFunction, deinitializeFunction, context);
}
public CustomLayer(String id,
long context,
long initializeFunction,
long renderFunction,
long deinitializeFunction) {
initialize(id, initializeFunction, renderFunction, deinitializeFunction, context);
}
public CustomLayer(long nativePtr) {
super(nativePtr);
}
public CustomLayer(long nativePtr) {
super(nativePtr);
}
public void update() {
nativeUpdate();
}
public void update() {
nativeUpdate();
}
protected native void initialize(String id, long initializeFunction, long renderFunction, long deinitializeFunction, long context);
protected native void initialize(String id, long initializeFunction, long renderFunction, long deinitializeFunction,
long context);
protected native void nativeUpdate();
protected native void nativeUpdate();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -1,12 +1,11 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.UiThread;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A filled polygon with an optional stroked border.
@@ -16,218 +15,222 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
@UiThread
public class FillLayer extends Layer {
/**
* Creates a FillLayer.
*
* @param nativePtr pointer used by core
*/
public FillLayer(long nativePtr) {
super(nativePtr);
/**
* Creates a FillLayer.
*
* @param nativePtr pointer used by core
*/
public FillLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a FillLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public FillLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public FillLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public FillLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public FillLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public FillLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
/**
* Get the FillAntialias property
*
* @return property wrapper value around Boolean
*/
@SuppressWarnings("unchecked")
public PropertyValue<Boolean> getFillAntialias() {
return (PropertyValue<Boolean>) new PropertyValue(nativeGetFillAntialias());
}
/**
* Get the FillOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getFillOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetFillOpacity());
}
/**
* Get the FillColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillColor());
}
/**
* The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the
* color's opacity will not affect the opacity of the 1px stroke, if it is used.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getFillColorAsInt() {
PropertyValue<String> value = getFillColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("fill-color was set as a Function");
}
}
/**
* Creates a FillLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public FillLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public FillLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public FillLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public FillLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
/**
* Get the FillOutlineColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillOutlineColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillOutlineColor());
}
/**
* The outline color of the fill. Matches the value of `fill-color` if unspecified.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getFillOutlineColorAsInt() {
PropertyValue<String> value = getFillOutlineColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("fill-outline-color was set as a Function");
}
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public FillLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
/**
* Get the FillTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getFillTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetFillTranslate());
}
// Property getters
/**
* Get the FillTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillTranslateAnchor());
}
/**
* Get the FillAntialias property
*
* @return property wrapper value around Boolean
*/
@SuppressWarnings("unchecked")
public PropertyValue<Boolean> getFillAntialias() {
return (PropertyValue<Boolean>) new PropertyValue(nativeGetFillAntialias());
}
/**
* Get the FillOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getFillOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetFillOpacity());
}
/**
* Get the FillColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillColor());
}
/**
* The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getFillColorAsInt() {
PropertyValue<String> value = getFillColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("fill-color was set as a Function");
}
}
/**
* Get the FillPattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillPattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillPattern());
}
/**
* Get the FillOutlineColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillOutlineColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillOutlineColor());
}
/**
* The outline color of the fill. Matches the value of `fill-color` if unspecified.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getFillOutlineColorAsInt() {
PropertyValue<String> value = getFillOutlineColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("fill-outline-color was set as a Function");
}
}
private native Object nativeGetFillAntialias();
/**
* Get the FillTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getFillTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetFillTranslate());
}
/**
* Get the FillTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillTranslateAnchor());
}
/**
* Get the FillPattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getFillPattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetFillPattern());
}
private native Object nativeGetFillAntialias();
private native Object nativeGetFillOpacity();
private native Object nativeGetFillOpacity();
private native Object nativeGetFillColor();
private native Object nativeGetFillColor();
private native Object nativeGetFillOutlineColor();
private native Object nativeGetFillOutlineColor();
private native Object nativeGetFillTranslate();
private native Object nativeGetFillTranslate();
private native Object nativeGetFillTranslateAnchor();
private native Object nativeGetFillTranslateAnchor();
private native Object nativeGetFillPattern();
private native Object nativeGetFillPattern();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -10,221 +10,221 @@ import java.util.Collections;
*/
public class Filter {
/**
* Base {@link Filter} statement. Subclassed to provide concrete statements.
*/
public abstract static class Statement {
protected final String operator;
/**
* Base {@link 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();
public Statement(String operator) {
this.operator = operator;
}
/**
* 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
* Generate a raw array representation of the filter
*
* @param statements the collection of statements
* @return the statements compounded
* @return the filter represented as an array
*/
public static Statement all(Statement... statements) {
return new CompoundStatement("all", statements);
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;
}
/**
* Groups a collection of statements in an 'any' relationship
*
* @param statements the collection of statements
* @return the statements compounded
* {@inheritDoc}
*/
public static Statement any(Statement... statements) {
return new CompoundStatement("any", statements);
@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 'none' relationship
*
* @param statements the collection of statements
* @return the statements compounded
*/
public static Statement none(Statement... statements) {
return new CompoundStatement("none", statements);
}
/**
* 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);
}
/**
* Check the property's existence
*
* @param key the property key
* @return the statement
*/
public static Statement has(String key) {
return new SimpleStatement("has", key);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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 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's existence
*
* @param key the property key
* @return the statement
*/
public static Statement has(String key) {
return new SimpleStatement("has", key);
}
/**
* 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'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 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 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 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 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 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 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 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 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 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 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 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);
}
/**
* 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

@@ -19,119 +19,119 @@ import java.util.Map;
*/
public class Function<T> {
/**
* A stop represents a certain point in the range of this function
*
* @param <I> input
* @param <O> output
*/
public static class Stop<I, O> {
public final I in;
public final O out;
/**
* A stop represents a certain point in the range of this function
*
* @param <I> input
* @param <O> output
*/
public static class Stop<I, O> {
public final I in;
public final O out;
Stop(I in, O out) {
this.in = in;
this.out = out;
}
/**
* @return an array representation of the Stop
*/
Object[] toValueObject() {
return new Object[]{in, out};
}
@Override
public String toString() {
return String.format("[%s, %s]", in, out);
}
Stop(I in, O out) {
this.in = in;
this.out = out;
}
/**
* 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 stops the stops that define the function
* @param <T> the property type
* @return the {@link Function}
* @return an array representation of the Stop
*/
@SafeVarargs
public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) {
return new Function<T>(stops);
Object[] toValueObject() {
return new Object[] {in, out};
}
@Override
public String toString() {
return String.format("[%s, %s]", in, out);
}
}
/**
* 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 stops the stops that define the function
* @param base the exponential base of the interpolation curve - Default 1
* @param <T> the property type
* @return the {@link Function}
*/
@SafeVarargs
public static <T> Function<T> zoom(
@FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base,
@NonNull @Size(min = 1) Stop<Float, T>... stops) {
return new Function<T>(stops)
.withBase(base);
/**
* 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 stops the stops that define the function
* @param <T> the property type
* @return the {@link Function}
*/
@SafeVarargs
public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) {
return new Function<T>(stops);
}
/**
* 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 stops the stops that define the function
* @param base the exponential base of the interpolation curve - Default 1
* @param <T> the property type
* @return the {@link Function}
*/
@SafeVarargs
public static <T> Function<T> zoom(
@FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base,
@NonNull @Size(min = 1) Stop<Float, T>... stops) {
return new Function<T>(stops)
.withBase(base);
}
/**
* Creates a stop to use in a {@link Function}
*
* @param in the input for the stop
* @param output the output for the stop
* @param <T> the output property type
* @return the {@link Stop}
*/
public static <T> Stop<Float, T> stop(float in, Property<T> output) {
return new Stop<>(in, output.value);
}
private final Stop<Float, T>[] stops;
private Float base;
Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) {
this.stops = stops;
}
Function<T> withBase(float base) {
this.base = base;
return this;
}
/**
* @return the base
*/
@Nullable
public Float getBase() {
return base;
}
/**
* @return the stops in this function
*/
public Stop<Float, T>[] getStops() {
return stops;
}
Map<String, Object> toValueObject() {
Object[] stopsValue = new Object[stops.length];
for (int i = 0; i < stopsValue.length; i++) {
Stop stop = stops[i];
stopsValue[i] = stop.toValueObject();
}
/**
* Creates a stop to use in a {@link Function}
*
* @param in the input for the stop
* @param output the output for the stop
* @param <T> the output property type
* @return the {@link Stop}
*/
public static <T> Stop<Float, T> stop(float in, Property<T> output) {
return new Stop<>(in, output.value);
}
private final Stop<Float, T>[] stops;
private Float base;
Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) {
this.stops = stops;
}
Function<T> withBase(float base) {
this.base = base;
return this;
}
/**
* @return the base
*/
@Nullable
public Float getBase() {
return base;
}
/**
* @return the stops in this function
*/
public Stop<Float, T>[] getStops() {
return stops;
}
Map<String, Object> toValueObject() {
Object[] stopsValue = new Object[stops.length];
for (int i = 0; i < stopsValue.length; i++) {
Stop stop = stops[i];
stopsValue[i] = stop.toValueObject();
}
Map<String, Object> value = new HashMap<>();
if (base != null) {
value.put("base", base);
}
value.put("stops", stopsValue);
return value;
Map<String, Object> value = new HashMap<>();
if (base != null) {
value.put("base", base);
}
value.put("stops", stopsValue);
return value;
}
}

View File

@@ -7,83 +7,83 @@ import android.support.annotation.NonNull;
*/
public abstract class Layer {
private long nativePtr;
private boolean invalidated;
private long nativePtr;
private boolean invalidated;
public Layer(long nativePtr) {
this.nativePtr = nativePtr;
public Layer(long nativePtr) {
this.nativePtr = nativePtr;
}
public Layer() {
}
public void setProperties(@NonNull Property<?>... properties) {
if (properties.length == 0) {
return;
}
public Layer() {
for (Property<?> property : properties) {
Object converted = convertValue(property.value);
if (property instanceof PaintProperty) {
nativeSetPaintProperty(property.name, converted);
} else {
nativeSetLayoutProperty(property.name, converted);
}
}
}
public void setProperties(@NonNull Property<?>... properties) {
if (properties.length == 0) {
return;
}
public String getId() {
return nativeGetId();
}
for (Property<?> property : properties) {
Object converted = convertValue(property.value);
if (property instanceof PaintProperty) {
nativeSetPaintProperty(property.name, converted);
} else {
nativeSetLayoutProperty(property.name, converted);
}
}
}
public PropertyValue<String> getVisibility() {
return new PropertyValue<>(nativeGetVisibility());
}
public String getId() {
return nativeGetId();
}
public float getMinZoom() {
return nativeGetMinZoom();
}
public PropertyValue<String> getVisibility() {
return new PropertyValue<>(nativeGetVisibility());
}
public float getMaxZoom() {
return nativeGetMaxZoom();
}
public float getMinZoom() {
return nativeGetMinZoom();
}
public void setMinZoom(float zoom) {
nativeSetMinZoom(zoom);
}
public float getMaxZoom() {
return nativeGetMaxZoom();
}
public void setMaxZoom(float zoom) {
nativeSetMaxZoom(zoom);
}
public void setMinZoom(float zoom) {
nativeSetMinZoom(zoom);
}
@Override
protected native void finalize() throws Throwable;
public void setMaxZoom(float zoom) {
nativeSetMaxZoom(zoom);
}
protected native String nativeGetId();
@Override
protected native void finalize() throws Throwable;
protected native Object nativeGetVisibility();
protected native String nativeGetId();
protected native void nativeSetLayoutProperty(String name, Object value);
protected native Object nativeGetVisibility();
protected native void nativeSetPaintProperty(String name, Object value);
protected native void nativeSetLayoutProperty(String name, Object value);
protected native void nativeSetFilter(Object[] filter);
protected native void nativeSetPaintProperty(String name, Object value);
protected native void nativeSetSourceLayer(String sourceLayer);
protected native void nativeSetFilter(Object[] filter);
protected native float nativeGetMinZoom();
protected native void nativeSetSourceLayer(String sourceLayer);
protected native float nativeGetMaxZoom();
protected native float nativeGetMinZoom();
protected native void nativeSetMinZoom(float zoom);
protected native float nativeGetMaxZoom();
protected native void nativeSetMaxZoom(float zoom);
protected native void nativeSetMinZoom(float zoom);
public long getNativePtr() {
return nativePtr;
}
protected native void nativeSetMaxZoom(float zoom);
public long getNativePtr() {
return nativePtr;
}
private Object convertValue(Object value) {
return value != null && value instanceof Function ? ((Function) value).toValueObject() : value;
}
private Object convertValue(Object value) {
return value != null && value instanceof Function ? ((Function) value).toValueObject() : value;
}
}

View File

@@ -2,8 +2,8 @@ package com.mapbox.mapboxsdk.style.layers;
class LayoutProperty<T> extends Property<T> {
LayoutProperty(String name, T value) {
super(name, value);
}
LayoutProperty(String name, T value) {
super(name, value);
}
}

View File

@@ -1,12 +1,11 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.UiThread;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A stroked line.
@@ -16,286 +15,288 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
@UiThread
public class LineLayer extends Layer {
/**
* Creates a LineLayer.
*
* @param nativePtr pointer used by core
*/
public LineLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a LineLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public LineLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public LineLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public LineLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public LineLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
/**
* Creates a LineLayer.
*
* @param nativePtr pointer used by core
*/
public LineLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a LineLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public LineLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public LineLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
this.setFilter(filter.toArray());
}
/**
* Set an array of filters.
*
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
nativeSetFilter(filter);
}
/**
* Set an array of filters.
*
* @param filter tthe filter array to set
* @return This
*/
public LineLayer withFilter(Object[] filter) {
setFilter(filter);
return this;
}
/**
* Set a single filter.
*
* @param filter the filter to set
* @return This
*/
public LineLayer withFilter(Filter.Statement filter) {
setFilter(filter);
return this;
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public LineLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
/**
* Get the LineCap property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineCap() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineCap());
}
/**
* Get the LineJoin property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineJoin() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineJoin());
}
/**
* Get the LineMiterLimit property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineMiterLimit() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineMiterLimit());
}
/**
* Get the LineRoundLimit property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineRoundLimit() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineRoundLimit());
}
/**
* Get the LineOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineOpacity());
}
/**
* Get the LineColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineColor());
}
/**
* The color with which the line will be drawn.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getLineColorAsInt() {
PropertyValue<String> value = getLineColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("line-color was set as a Function");
}
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public LineLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
/**
* Get the LineTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getLineTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineTranslate());
}
// Property getters
/**
* Get the LineTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineTranslateAnchor());
}
/**
* Get the LineCap property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineCap() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineCap());
}
/**
* Get the LineJoin property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineJoin() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineJoin());
}
/**
* Get the LineMiterLimit property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineMiterLimit() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineMiterLimit());
}
/**
* Get the LineRoundLimit property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineRoundLimit() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineRoundLimit());
}
/**
* Get the LineOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineOpacity());
}
/**
* Get the LineColor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineColor() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineColor());
}
/**
* The color with which the line will be drawn.
*
* @return int representation of a rgba string color
* @throws RuntimeException thrown if property isn't a value
*/
@ColorInt
public int getLineColorAsInt() {
PropertyValue<String> value = getLineColor();
if (value.isValue()) {
return rgbaToColor(value.getValue());
} else {
throw new RuntimeException("line-color was set as a Function");
}
}
/**
* Get the LineWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineWidth());
}
/**
* Get the LineTranslate property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getLineTranslate() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineTranslate());
}
/**
* Get the LineTranslateAnchor property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLineTranslateAnchor() {
return (PropertyValue<String>) new PropertyValue(nativeGetLineTranslateAnchor());
}
/**
* Get the LineWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineWidth());
}
/**
* Get the LineGapWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineGapWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineGapWidth());
}
/**
* Get the LineOffset property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineOffset() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineOffset());
}
/**
* Get the LineBlur property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineBlur() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineBlur());
}
/**
* Get the LineDasharray property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getLineDasharray() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineDasharray());
}
/**
* Get the LinePattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLinePattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetLinePattern());
}
private native Object nativeGetLineCap();
/**
* Get the LineGapWidth property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineGapWidth() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineGapWidth());
}
private native Object nativeGetLineJoin();
/**
* Get the LineOffset property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineOffset() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineOffset());
}
private native Object nativeGetLineMiterLimit();
/**
* Get the LineBlur property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getLineBlur() {
return (PropertyValue<Float>) new PropertyValue(nativeGetLineBlur());
}
private native Object nativeGetLineRoundLimit();
/**
* Get the LineDasharray property
*
* @return property wrapper value around Float[]
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float[]> getLineDasharray() {
return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineDasharray());
}
private native Object nativeGetLineOpacity();
/**
* Get the LinePattern property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getLinePattern() {
return (PropertyValue<String>) new PropertyValue(nativeGetLinePattern());
}
private native Object nativeGetLineColor();
private native Object nativeGetLineCap();
private native Object nativeGetLineTranslate();
private native Object nativeGetLineJoin();
private native Object nativeGetLineTranslateAnchor();
private native Object nativeGetLineMiterLimit();
private native Object nativeGetLineWidth();
private native Object nativeGetLineRoundLimit();
private native Object nativeGetLineGapWidth();
private native Object nativeGetLineOpacity();
private native Object nativeGetLineOffset();
private native Object nativeGetLineColor();
private native Object nativeGetLineBlur();
private native Object nativeGetLineTranslate();
private native Object nativeGetLineDasharray();
private native Object nativeGetLineTranslateAnchor();
private native Object nativeGetLinePattern();
private native Object nativeGetLineWidth();
private native Object nativeGetLineGapWidth();
private native Object nativeGetLineOffset();
private native Object nativeGetLineBlur();
private native Object nativeGetLineDasharray();
private native Object nativeGetLinePattern();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -5,7 +5,7 @@ package com.mapbox.mapboxsdk.style.layers;
*/
public class NoSuchLayerException extends Exception {
public NoSuchLayerException(String message) {
super(message);
}
public NoSuchLayerException(String message) {
super(message);
}
}

View File

@@ -2,8 +2,8 @@ package com.mapbox.mapboxsdk.style.layers;
class PaintProperty<T> extends Property<T> {
PaintProperty(String name, T value) {
super(name, value);
}
PaintProperty(String name, T value) {
super(name, value);
}
}

View File

@@ -1,5 +1,5 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.StringDef;
@@ -11,448 +11,477 @@ import java.lang.annotation.RetentionPolicy;
*/
public abstract class Property<T> {
//VISIBILITY: Whether this layer is displayed.
//VISIBILITY: Whether this layer is displayed.
/**
* The layer is shown.
*/
public static final String VISIBLE = "visible";
/**
* The layer is hidden.
*/
public static final String NONE = "none";
/**
* The layer is shown.
*/
public static final String VISIBLE = "visible";
/**
* The layer is hidden.
*/
public static final String NONE = "none";
@StringDef({
VISIBLE,
NONE
})
@Retention(RetentionPolicy.SOURCE)
public @interface VISIBILITY {}
@StringDef( {
VISIBLE,
NONE
})
@Retention(RetentionPolicy.SOURCE)
public @interface VISIBILITY {
}
//LINE_CAP: The display of line endings.
//LINE_CAP: The display of line endings.
/**
* A cap with a squared-off end which is drawn to the exact endpoint of the line.
*/
public static final String LINE_CAP_BUTT = "butt";
/**
* A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.
*/
public static final String LINE_CAP_ROUND = "round";
/**
* A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.
*/
public static final String LINE_CAP_SQUARE = "square";
/**
* A cap with a squared-off end which is drawn to the exact endpoint of the line.
*/
public static final String LINE_CAP_BUTT = "butt";
/**
* A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's
* width and centered on the endpoint of the line.
*/
public static final String LINE_CAP_ROUND = "round";
/**
* A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the
* line's width.
*/
public static final String LINE_CAP_SQUARE = "square";
/**
* The display of line endings.
*/
@StringDef({
LINE_CAP_BUTT,
LINE_CAP_ROUND,
LINE_CAP_SQUARE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_CAP {}
/**
* The display of line endings.
*/
@StringDef( {
LINE_CAP_BUTT,
LINE_CAP_ROUND,
LINE_CAP_SQUARE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_CAP {
}
//LINE_JOIN: The display of lines when joining.
//LINE_JOIN: The display of lines when joining.
/**
* A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.
*/
public static final String LINE_JOIN_BEVEL = "bevel";
/**
* A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.
*/
public static final String LINE_JOIN_ROUND = "round";
/**
* A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until they meet.
*/
public static final String LINE_JOIN_MITER = "miter";
/**
* A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the
* line's width.
*/
public static final String LINE_JOIN_BEVEL = "bevel";
/**
* A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's
* width and centered on the endpoint of the line.
*/
public static final String LINE_JOIN_ROUND = "round";
/**
* A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until
* they meet.
*/
public static final String LINE_JOIN_MITER = "miter";
/**
* The display of lines when joining.
*/
@StringDef({
LINE_JOIN_BEVEL,
LINE_JOIN_ROUND,
LINE_JOIN_MITER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_JOIN {}
/**
* The display of lines when joining.
*/
@StringDef( {
LINE_JOIN_BEVEL,
LINE_JOIN_ROUND,
LINE_JOIN_MITER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_JOIN {
}
//SYMBOL_PLACEMENT: Label placement relative to its geometry.
//SYMBOL_PLACEMENT: Label placement relative to its geometry.
/**
* The label is placed at the point where the geometry is located.
*/
public static final String SYMBOL_PLACEMENT_POINT = "point";
/**
* The label is placed along the line of the geometry. Can only be used on LineString and Polygon geometries.
*/
public static final String SYMBOL_PLACEMENT_LINE = "line";
/**
* The label is placed at the point where the geometry is located.
*/
public static final String SYMBOL_PLACEMENT_POINT = "point";
/**
* The label is placed along the line of the geometry. Can only be used on LineString and Polygon geometries.
*/
public static final String SYMBOL_PLACEMENT_LINE = "line";
/**
* Label placement relative to its geometry.
*/
@StringDef({
SYMBOL_PLACEMENT_POINT,
SYMBOL_PLACEMENT_LINE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SYMBOL_PLACEMENT {}
/**
* Label placement relative to its geometry.
*/
@StringDef( {
SYMBOL_PLACEMENT_POINT,
SYMBOL_PLACEMENT_LINE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SYMBOL_PLACEMENT {
}
//ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons.
//ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons.
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line.
*/
public static final String ICON_ROTATION_ALIGNMENT_MAP = "map";
/**
* Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}.
*/
public static final String ICON_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}.
*/
public static final String ICON_ROTATION_ALIGNMENT_AUTO = "auto";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When
* {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line.
*/
public static final String ICON_ROTATION_ALIGNMENT_MAP = "map";
/**
* Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of
* {@link SYMBOL_PLACEMENT}.
*/
public static final String ICON_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to
* {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to
* {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}.
*/
public static final String ICON_ROTATION_ALIGNMENT_AUTO = "auto";
/**
* In combination with `symbol-placement`, determines the rotation behavior of icons.
*/
@StringDef({
ICON_ROTATION_ALIGNMENT_MAP,
ICON_ROTATION_ALIGNMENT_VIEWPORT,
ICON_ROTATION_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_ROTATION_ALIGNMENT {}
/**
* In combination with `symbol-placement`, determines the rotation behavior of icons.
*/
@StringDef( {
ICON_ROTATION_ALIGNMENT_MAP,
ICON_ROTATION_ALIGNMENT_VIEWPORT,
ICON_ROTATION_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_ROTATION_ALIGNMENT {
}
//ICON_TEXT_FIT: Scales the icon to fit around the associated text.
//ICON_TEXT_FIT: Scales the icon to fit around the associated text.
/**
* The icon is displayed at its intrinsic aspect ratio.
*/
public static final String ICON_TEXT_FIT_NONE = "none";
/**
* The icon is scaled in the x-dimension to fit the width of the text.
*/
public static final String ICON_TEXT_FIT_WIDTH = "width";
/**
* The icon is scaled in the y-dimension to fit the height of the text.
*/
public static final String ICON_TEXT_FIT_HEIGHT = "height";
/**
* The icon is scaled in both x- and y-dimensions.
*/
public static final String ICON_TEXT_FIT_BOTH = "both";
/**
* The icon is displayed at its intrinsic aspect ratio.
*/
public static final String ICON_TEXT_FIT_NONE = "none";
/**
* The icon is scaled in the x-dimension to fit the width of the text.
*/
public static final String ICON_TEXT_FIT_WIDTH = "width";
/**
* The icon is scaled in the y-dimension to fit the height of the text.
*/
public static final String ICON_TEXT_FIT_HEIGHT = "height";
/**
* The icon is scaled in both x- and y-dimensions.
*/
public static final String ICON_TEXT_FIT_BOTH = "both";
/**
* Scales the icon to fit around the associated text.
*/
@StringDef({
ICON_TEXT_FIT_NONE,
ICON_TEXT_FIT_WIDTH,
ICON_TEXT_FIT_HEIGHT,
ICON_TEXT_FIT_BOTH,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_TEXT_FIT {}
/**
* Scales the icon to fit around the associated text.
*/
@StringDef( {
ICON_TEXT_FIT_NONE,
ICON_TEXT_FIT_WIDTH,
ICON_TEXT_FIT_HEIGHT,
ICON_TEXT_FIT_BOTH,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_TEXT_FIT {
}
//TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched.
//TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched.
/**
* The text is aligned to the plane of the map.
*/
public static final String TEXT_PITCH_ALIGNMENT_MAP = "map";
/**
* The text is aligned to the plane of the viewport.
*/
public static final String TEXT_PITCH_ALIGNMENT_VIEWPORT = "viewport";
/**
* Automatically matches the value of {@link TEXT_ROTATION_ALIGNMENT}.
*/
public static final String TEXT_PITCH_ALIGNMENT_AUTO = "auto";
/**
* The text is aligned to the plane of the map.
*/
public static final String TEXT_PITCH_ALIGNMENT_MAP = "map";
/**
* The text is aligned to the plane of the viewport.
*/
public static final String TEXT_PITCH_ALIGNMENT_VIEWPORT = "viewport";
/**
* Automatically matches the value of {@link TEXT_ROTATION_ALIGNMENT}.
*/
public static final String TEXT_PITCH_ALIGNMENT_AUTO = "auto";
/**
* Orientation of text when map is pitched.
*/
@StringDef({
TEXT_PITCH_ALIGNMENT_MAP,
TEXT_PITCH_ALIGNMENT_VIEWPORT,
TEXT_PITCH_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_PITCH_ALIGNMENT {}
/**
* Orientation of text when map is pitched.
*/
@StringDef( {
TEXT_PITCH_ALIGNMENT_MAP,
TEXT_PITCH_ALIGNMENT_VIEWPORT,
TEXT_PITCH_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_PITCH_ALIGNMENT {
}
//TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
//TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual
// glyphs forming the text.
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line.
*/
public static final String TEXT_ROTATION_ALIGNMENT_MAP = "map";
/**
* Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}.
*/
public static final String TEXT_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}.
*/
public static final String TEXT_ROTATION_ALIGNMENT_AUTO = "auto";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When
* {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line.
*/
public static final String TEXT_ROTATION_ALIGNMENT_MAP = "map";
/**
* Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of
* {@link SYMBOL_PLACEMENT}.
*/
public static final String TEXT_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
/**
* When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to
* {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to
* {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}.
*/
public static final String TEXT_ROTATION_ALIGNMENT_AUTO = "auto";
/**
* In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
*/
@StringDef({
TEXT_ROTATION_ALIGNMENT_MAP,
TEXT_ROTATION_ALIGNMENT_VIEWPORT,
TEXT_ROTATION_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_ROTATION_ALIGNMENT {}
/**
* In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
*/
@StringDef( {
TEXT_ROTATION_ALIGNMENT_MAP,
TEXT_ROTATION_ALIGNMENT_VIEWPORT,
TEXT_ROTATION_ALIGNMENT_AUTO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_ROTATION_ALIGNMENT {
}
//TEXT_JUSTIFY: Text justification options.
//TEXT_JUSTIFY: Text justification options.
/**
* The text is aligned to the left.
*/
public static final String TEXT_JUSTIFY_LEFT = "left";
/**
* The text is centered.
*/
public static final String TEXT_JUSTIFY_CENTER = "center";
/**
* The text is aligned to the right.
*/
public static final String TEXT_JUSTIFY_RIGHT = "right";
/**
* The text is aligned to the left.
*/
public static final String TEXT_JUSTIFY_LEFT = "left";
/**
* The text is centered.
*/
public static final String TEXT_JUSTIFY_CENTER = "center";
/**
* The text is aligned to the right.
*/
public static final String TEXT_JUSTIFY_RIGHT = "right";
/**
* Text justification options.
*/
@StringDef({
TEXT_JUSTIFY_LEFT,
TEXT_JUSTIFY_CENTER,
TEXT_JUSTIFY_RIGHT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_JUSTIFY {}
/**
* Text justification options.
*/
@StringDef( {
TEXT_JUSTIFY_LEFT,
TEXT_JUSTIFY_CENTER,
TEXT_JUSTIFY_RIGHT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_JUSTIFY {
}
//TEXT_ANCHOR: Part of the text placed closest to the anchor.
//TEXT_ANCHOR: Part of the text placed closest to the anchor.
/**
* The center of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_CENTER = "center";
/**
* The left side of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_LEFT = "left";
/**
* The right side of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_RIGHT = "right";
/**
* The top of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP = "top";
/**
* The bottom of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM = "bottom";
/**
* The top left corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP_LEFT = "top-left";
/**
* The top right corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP_RIGHT = "top-right";
/**
* The bottom left corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM_LEFT = "bottom-left";
/**
* The bottom right corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM_RIGHT = "bottom-right";
/**
* The center of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_CENTER = "center";
/**
* The left side of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_LEFT = "left";
/**
* The right side of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_RIGHT = "right";
/**
* The top of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP = "top";
/**
* The bottom of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM = "bottom";
/**
* The top left corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP_LEFT = "top-left";
/**
* The top right corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_TOP_RIGHT = "top-right";
/**
* The bottom left corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM_LEFT = "bottom-left";
/**
* The bottom right corner of the text is placed closest to the anchor.
*/
public static final String TEXT_ANCHOR_BOTTOM_RIGHT = "bottom-right";
/**
* Part of the text placed closest to the anchor.
*/
@StringDef({
TEXT_ANCHOR_CENTER,
TEXT_ANCHOR_LEFT,
TEXT_ANCHOR_RIGHT,
TEXT_ANCHOR_TOP,
TEXT_ANCHOR_BOTTOM,
TEXT_ANCHOR_TOP_LEFT,
TEXT_ANCHOR_TOP_RIGHT,
TEXT_ANCHOR_BOTTOM_LEFT,
TEXT_ANCHOR_BOTTOM_RIGHT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_ANCHOR {}
/**
* Part of the text placed closest to the anchor.
*/
@StringDef( {
TEXT_ANCHOR_CENTER,
TEXT_ANCHOR_LEFT,
TEXT_ANCHOR_RIGHT,
TEXT_ANCHOR_TOP,
TEXT_ANCHOR_BOTTOM,
TEXT_ANCHOR_TOP_LEFT,
TEXT_ANCHOR_TOP_RIGHT,
TEXT_ANCHOR_BOTTOM_LEFT,
TEXT_ANCHOR_BOTTOM_RIGHT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_ANCHOR {
}
//TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property.
//TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property.
/**
* The text is not altered.
*/
public static final String TEXT_TRANSFORM_NONE = "none";
/**
* Forces all letters to be displayed in uppercase.
*/
public static final String TEXT_TRANSFORM_UPPERCASE = "uppercase";
/**
* Forces all letters to be displayed in lowercase.
*/
public static final String TEXT_TRANSFORM_LOWERCASE = "lowercase";
/**
* The text is not altered.
*/
public static final String TEXT_TRANSFORM_NONE = "none";
/**
* Forces all letters to be displayed in uppercase.
*/
public static final String TEXT_TRANSFORM_UPPERCASE = "uppercase";
/**
* Forces all letters to be displayed in lowercase.
*/
public static final String TEXT_TRANSFORM_LOWERCASE = "lowercase";
/**
* Specifies how to capitalize text, similar to the CSS `text-transform` property.
*/
@StringDef({
TEXT_TRANSFORM_NONE,
TEXT_TRANSFORM_UPPERCASE,
TEXT_TRANSFORM_LOWERCASE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_TRANSFORM {}
/**
* Specifies how to capitalize text, similar to the CSS `text-transform` property.
*/
@StringDef( {
TEXT_TRANSFORM_NONE,
TEXT_TRANSFORM_UPPERCASE,
TEXT_TRANSFORM_LOWERCASE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_TRANSFORM {
}
//FILL_TRANSLATE_ANCHOR: Controls the translation reference point.
//FILL_TRANSLATE_ANCHOR: Controls the translation reference point.
/**
* The fill is translated relative to the map.
*/
public static final String FILL_TRANSLATE_ANCHOR_MAP = "map";
/**
* The fill is translated relative to the viewport.
*/
public static final String FILL_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* The fill is translated relative to the map.
*/
public static final String FILL_TRANSLATE_ANCHOR_MAP = "map";
/**
* The fill is translated relative to the viewport.
*/
public static final String FILL_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Controls the translation reference point.
*/
@StringDef({
FILL_TRANSLATE_ANCHOR_MAP,
FILL_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface FILL_TRANSLATE_ANCHOR {}
/**
* Controls the translation reference point.
*/
@StringDef( {
FILL_TRANSLATE_ANCHOR_MAP,
FILL_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface FILL_TRANSLATE_ANCHOR {
}
//LINE_TRANSLATE_ANCHOR: Controls the translation reference point.
//LINE_TRANSLATE_ANCHOR: Controls the translation reference point.
/**
* The line is translated relative to the map.
*/
public static final String LINE_TRANSLATE_ANCHOR_MAP = "map";
/**
* The line is translated relative to the viewport.
*/
public static final String LINE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* The line is translated relative to the map.
*/
public static final String LINE_TRANSLATE_ANCHOR_MAP = "map";
/**
* The line is translated relative to the viewport.
*/
public static final String LINE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Controls the translation reference point.
*/
@StringDef({
LINE_TRANSLATE_ANCHOR_MAP,
LINE_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_TRANSLATE_ANCHOR {}
/**
* Controls the translation reference point.
*/
@StringDef( {
LINE_TRANSLATE_ANCHOR_MAP,
LINE_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LINE_TRANSLATE_ANCHOR {
}
//ICON_TRANSLATE_ANCHOR: Controls the translation reference point.
//ICON_TRANSLATE_ANCHOR: Controls the translation reference point.
/**
* Icons are translated relative to the map.
*/
public static final String ICON_TRANSLATE_ANCHOR_MAP = "map";
/**
* Icons are translated relative to the viewport.
*/
public static final String ICON_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Icons are translated relative to the map.
*/
public static final String ICON_TRANSLATE_ANCHOR_MAP = "map";
/**
* Icons are translated relative to the viewport.
*/
public static final String ICON_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Controls the translation reference point.
*/
@StringDef({
ICON_TRANSLATE_ANCHOR_MAP,
ICON_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_TRANSLATE_ANCHOR {}
/**
* Controls the translation reference point.
*/
@StringDef( {
ICON_TRANSLATE_ANCHOR_MAP,
ICON_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ICON_TRANSLATE_ANCHOR {
}
//TEXT_TRANSLATE_ANCHOR: Controls the translation reference point.
//TEXT_TRANSLATE_ANCHOR: Controls the translation reference point.
/**
* The text is translated relative to the map.
*/
public static final String TEXT_TRANSLATE_ANCHOR_MAP = "map";
/**
* The text is translated relative to the viewport.
*/
public static final String TEXT_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* The text is translated relative to the map.
*/
public static final String TEXT_TRANSLATE_ANCHOR_MAP = "map";
/**
* The text is translated relative to the viewport.
*/
public static final String TEXT_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Controls the translation reference point.
*/
@StringDef({
TEXT_TRANSLATE_ANCHOR_MAP,
TEXT_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_TRANSLATE_ANCHOR {}
/**
* Controls the translation reference point.
*/
@StringDef( {
TEXT_TRANSLATE_ANCHOR_MAP,
TEXT_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TEXT_TRANSLATE_ANCHOR {
}
//CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point.
//CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point.
/**
* The circle is translated relative to the map.
*/
public static final String CIRCLE_TRANSLATE_ANCHOR_MAP = "map";
/**
* The circle is translated relative to the viewport.
*/
public static final String CIRCLE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* The circle is translated relative to the map.
*/
public static final String CIRCLE_TRANSLATE_ANCHOR_MAP = "map";
/**
* The circle is translated relative to the viewport.
*/
public static final String CIRCLE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
/**
* Controls the translation reference point.
*/
@StringDef({
CIRCLE_TRANSLATE_ANCHOR_MAP,
CIRCLE_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_TRANSLATE_ANCHOR {}
/**
* Controls the translation reference point.
*/
@StringDef( {
CIRCLE_TRANSLATE_ANCHOR_MAP,
CIRCLE_TRANSLATE_ANCHOR_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_TRANSLATE_ANCHOR {
}
//CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched.
//CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched.
/**
* Circles are scaled according to their apparent distance to the camera.
*/
public static final String CIRCLE_PITCH_SCALE_MAP = "map";
/**
* Circles are not scaled.
*/
public static final String CIRCLE_PITCH_SCALE_VIEWPORT = "viewport";
/**
* Circles are scaled according to their apparent distance to the camera.
*/
public static final String CIRCLE_PITCH_SCALE_MAP = "map";
/**
* Circles are not scaled.
*/
public static final String CIRCLE_PITCH_SCALE_VIEWPORT = "viewport";
/**
* Controls the scaling behavior of the circle when the map is pitched.
*/
@StringDef({
CIRCLE_PITCH_SCALE_MAP,
CIRCLE_PITCH_SCALE_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_PITCH_SCALE {}
/**
* Controls the scaling behavior of the circle when the map is pitched.
*/
@StringDef( {
CIRCLE_PITCH_SCALE_MAP,
CIRCLE_PITCH_SCALE_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_PITCH_SCALE {
}
//Class definition
public final String name;
public final T value;
//Class definition
public final String name;
public final T value;
/* package */ Property(String name, T value) {
this.name = name;
this.value = value;
}
/* package */ Property(String name, T value) {
this.name = name;
this.value = value;
}
}

View File

@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.Nullable;
import timber.log.Timber;
/**
@@ -8,48 +9,49 @@ import timber.log.Timber;
*/
public class PropertyValue<T> {
private final Object value;
private final Object value;
/* package */ PropertyValue(Object value) {
this.value = value;
}
/* package */ PropertyValue(Object value) {
this.value = value;
}
public boolean isNull() {
return value == null;
}
public boolean isNull() {
return value == null;
}
public boolean isFunction() {
return !isNull() && value instanceof Function;
}
public boolean isFunction() {
return !isNull() && value instanceof Function;
}
public boolean isValue() {
return !isNull() && !isFunction();
}
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;
}
@Nullable
public Function<T> getFunction() {
if (isFunction()) {
//noinspection unchecked
return (Function<T>) value;
} else {
Timber.w("not a function, try value");
return null;
}
}
@Nullable
public T getValue() {
if (isValue()) {
//noinspection unchecked
return (T) value;
} else {
Timber.w("not a value, try function");
return null;
}
@Nullable
public T getValue() {
if (isValue()) {
//noinspection unchecked
return (T) value;
} else {
Timber.w("not a value, try function");
return null;
}
}
@Override
public String toString() {
return String.format("%s (%s)", getClass().getSimpleName(), value != null ? value.getClass().getSimpleName() : null);
}
@Override
public String toString() {
return String.format("%s (%s)", getClass().getSimpleName(), value != null
? value.getClass().getSimpleName() : null);
}
}

View File

@@ -1,12 +1,8 @@
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.UiThread;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
import android.support.annotation.UiThread;
/**
* Raster map textures such as satellite imagery.
@@ -16,146 +12,146 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
@UiThread
public class RasterLayer extends Layer {
/**
* Creates a RasterLayer.
*
* @param nativePtr pointer used by core
*/
public RasterLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a RasterLayer.
*
* @param nativePtr pointer used by core
*/
public RasterLayer(long nativePtr) {
super(nativePtr);
}
/**
* Creates a RasterLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public RasterLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
/**
* Creates a RasterLayer.
*
* @param layerId the id of the layer
* @param sourceId the id of the source
*/
public RasterLayer(String layerId, String sourceId) {
initialize(layerId, sourceId);
}
protected native void initialize(String layerId, String sourceId);
protected native void initialize(String layerId, String sourceId);
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source layer.
*
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
nativeSetSourceLayer(sourceLayer);
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public RasterLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set the source Layer.
*
* @param sourceLayer the source layer to set
* @return This
*/
public RasterLayer withSourceLayer(String sourceLayer) {
setSourceLayer(sourceLayer);
return this;
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public RasterLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
/**
* Set a property or properties.
*
* @param properties the var-args properties
* @return This
*/
public RasterLayer withProperties(@NonNull Property<?>... properties) {
setProperties(properties);
return this;
}
// Property getters
// Property getters
/**
* Get the RasterOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterOpacity());
}
/**
* Get the RasterHueRotate property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterHueRotate() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterHueRotate());
}
/**
* Get the RasterBrightnessMin property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterBrightnessMin() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMin());
}
/**
* Get the RasterBrightnessMax property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterBrightnessMax() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMax());
}
/**
* Get the RasterSaturation property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterSaturation() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterSaturation());
}
/**
* Get the RasterContrast property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterContrast() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterContrast());
}
/**
* Get the RasterFadeDuration property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterFadeDuration() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterFadeDuration());
}
private native Object nativeGetRasterOpacity();
/**
* Get the RasterOpacity property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterOpacity() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterOpacity());
}
private native Object nativeGetRasterHueRotate();
/**
* Get the RasterHueRotate property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterHueRotate() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterHueRotate());
}
private native Object nativeGetRasterBrightnessMin();
/**
* Get the RasterBrightnessMin property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterBrightnessMin() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMin());
}
private native Object nativeGetRasterBrightnessMax();
/**
* Get the RasterBrightnessMax property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterBrightnessMax() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMax());
}
private native Object nativeGetRasterSaturation();
/**
* Get the RasterSaturation property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterSaturation() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterSaturation());
}
private native Object nativeGetRasterContrast();
/**
* Get the RasterContrast property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterContrast() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterContrast());
}
private native Object nativeGetRasterFadeDuration();
/**
* Get the RasterFadeDuration property
*
* @return property wrapper value around Float
*/
@SuppressWarnings("unchecked")
public PropertyValue<Float> getRasterFadeDuration() {
return (PropertyValue<Float>) new PropertyValue(nativeGetRasterFadeDuration());
}
private native Object nativeGetRasterOpacity();
private native Object nativeGetRasterHueRotate();
private native Object nativeGetRasterBrightnessMin();
private native Object nativeGetRasterBrightnessMax();
private native Object nativeGetRasterSaturation();
private native Object nativeGetRasterContrast();
private native Object nativeGetRasterFadeDuration();
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -5,8 +5,8 @@ package com.mapbox.mapboxsdk.style.sources;
*/
public class CannotAddSourceException extends RuntimeException {
public CannotAddSourceException(String message) {
super(message);
}
public CannotAddSourceException(String message) {
super(message);
}
}

View File

@@ -9,70 +9,72 @@ import java.util.HashMap;
*/
public class GeoJsonOptions extends HashMap<String, Object> {
/**
* Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).
*
* @param maxZoom the maximum zoom - Defaults to 18.
* @return the current instance for chaining
*/
public GeoJsonOptions withMaxZoom(int maxZoom) {
this.put("maxzoom", maxZoom);
return this;
}
/**
* Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).
*
* @param maxZoom the maximum zoom - Defaults to 18.
* @return the current instance for chaining
*/
public GeoJsonOptions withMaxZoom(int maxZoom) {
this.put("maxzoom", maxZoom);
return this;
}
/**
* Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile edges but slower performance).
*
* @param buffer the buffer size - Defaults to 128.
* @return the current instance for chaining
*/
public GeoJsonOptions withBuffer(int buffer) {
this.put("buffer", buffer);
return this;
}
/**
* Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
* edges but slower performance).
*
* @param buffer the buffer size - Defaults to 128.
* @return the current instance for chaining
*/
public GeoJsonOptions withBuffer(int buffer) {
this.put("buffer", buffer);
return this;
}
/**
* Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
*
* @param tolerance the tolerance - Defaults to 0.375
* @return the current instance for chaining
*/
public GeoJsonOptions withTolerance(float tolerance) {
this.put("tolerance", tolerance);
return this;
}
/**
* Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
*
* @param tolerance the tolerance - Defaults to 0.375
* @return the current instance for chaining
*/
public GeoJsonOptions withTolerance(float tolerance) {
this.put("tolerance", tolerance);
return this;
}
/**
* If the data is a collection of point features, setting this to true clusters the points by radius into groups.
*
* @param cluster cluster? - Defaults to false
* @return the current instance for chaining
*/
public GeoJsonOptions withCluster(boolean cluster) {
this.put("cluster", cluster);
return this;
}
/**
* If the data is a collection of point features, setting this to true clusters the points by radius into groups.
*
* @param cluster cluster? - Defaults to false
* @return the current instance for chaining
*/
public GeoJsonOptions withCluster(boolean cluster) {
this.put("cluster", cluster);
return this;
}
/**
* Max zoom to cluster points on.
*
* @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last zoom features are not clustered)
* @return the current instance for chaining
*/
public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
this.put("clusterMaxZoom", clusterMaxZoom);
return this;
}
/**
* Max zoom to cluster points on.
*
* @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last
* zoom features are not clustered)
* @return the current instance for chaining
*/
public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
this.put("clusterMaxZoom", clusterMaxZoom);
return this;
}
/**
* Radius of each cluster when clustering points, measured in 1/512ths of a tile.
*
* @param clusterRadius cluster radius - Defaults to 50
* @return the current instance for chaining
*/
public GeoJsonOptions withClusterRadius(int clusterRadius) {
this.put("clusterRadius", clusterRadius);
return this;
}
/**
* Radius of each cluster when clustering points, measured in 1/512ths of a tile.
*
* @param clusterRadius cluster radius - Defaults to 50
* @return the current instance for chaining
*/
public GeoJsonOptions withClusterRadius(int clusterRadius) {
this.put("clusterRadius", clusterRadius);
return this;
}
}

View File

@@ -14,166 +14,166 @@ import java.util.HashMap;
*/
public class GeoJsonSource extends Source {
/**
* Internal use
*
* @param nativePtr - pointer to native peer
*/
public GeoJsonSource(long nativePtr) {
super(nativePtr);
/**
* Internal use
*
* @param nativePtr - pointer to native peer
*/
public GeoJsonSource(long nativePtr) {
super(nativePtr);
}
/**
* Create an empty GeoJsonSource
*
* @param id the source id
*/
public GeoJsonSource(String id) {
initialize(id, null);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
}
/**
* Create an empty GeoJsonSource with non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param options options
*/
public GeoJsonSource(String id, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
}
/**
* Create a GeoJsonSource from a raw json string
*
* @param id the source id
* @param geoJson raw Json FeatureCollection
*/
public GeoJsonSource(String id, String geoJson) {
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
initialize(id, null);
setGeoJson(geoJson);
}
/**
* Create an empty GeoJsonSource
*
* @param id the source id
*/
public GeoJsonSource(String id) {
initialize(id, null);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
/**
* Create a GeoJsonSource from a raw json string and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param geoJson raw Json body
* @param options options
*/
public GeoJsonSource(String id, String geoJson, GeoJsonOptions options) {
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
initialize(id, options);
setGeoJson(geoJson);
}
/**
* Create an empty GeoJsonSource with non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param options options
*/
public GeoJsonSource(String id, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
}
/**
* Create a GeoJsonSource from a remote geo json file
*
* @param id the source id
* @param url remote json file
*/
public GeoJsonSource(String id, URL url) {
initialize(id, null);
nativeSetUrl(url.toExternalForm());
}
/**
* Create a GeoJsonSource from a raw json string
*
* @param id the source id
* @param geoJson raw Json FeatureCollection
*/
public GeoJsonSource(String id, String geoJson) {
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
initialize(id, null);
setGeoJson(geoJson);
}
/**
* Create a GeoJsonSource from a remote geo json file and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param url remote json file
* @param options options
*/
public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
initialize(id, options);
nativeSetUrl(url.toExternalForm());
}
/**
* Create a GeoJsonSource from a raw json string and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param geoJson raw Json body
* @param options options
*/
public GeoJsonSource(String id, String geoJson, GeoJsonOptions options) {
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
initialize(id, options);
setGeoJson(geoJson);
}
/**
* Create a GeoJsonSource from a {@link FeatureCollection}
*
* @param id the source id
* @param features the features
*/
public GeoJsonSource(String id, FeatureCollection features) {
initialize(id, null);
setGeoJson(features);
}
/**
* Create a GeoJsonSource from a remote geo json file
*
* @param id the source id
* @param url remote json file
*/
public GeoJsonSource(String id, URL url) {
initialize(id, null);
nativeSetUrl(url.toExternalForm());
}
/**
* Create a GeoJsonSource from a {@link FeatureCollection} and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param features the features
* @param options options
*/
public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(features);
}
/**
* Create a GeoJsonSource from a remote geo json file and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param url remote json file
* @param options options
*/
public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
initialize(id, options);
nativeSetUrl(url.toExternalForm());
}
/**
* Updates the GeoJson
*
* @param features the GeoJSON {@link FeatureCollection}
*/
public void setGeoJson(FeatureCollection features) {
checkValidity();
setGeoJson(features.toJson());
}
/**
* Create a GeoJsonSource from a {@link FeatureCollection}
*
* @param id the source id
* @param features the features
*/
public GeoJsonSource(String id, FeatureCollection features) {
initialize(id, null);
setGeoJson(features);
}
/**
* Updates the GeoJson
*
* @param json the raw GeoJson FeatureCollection string
*/
public void setGeoJson(String json) {
checkValidity();
setRawJson(json);
}
/**
* Create a GeoJsonSource from a {@link FeatureCollection} and non-default {@link GeoJsonOptions}
*
* @param id the source id
* @param features the features
* @param options options
*/
public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(features);
}
/**
* Updates the url
*
* @param url the GeoJSON FeatureCollection url
*/
public void setUrl(URL url) {
checkValidity();
setUrl(url.toExternalForm());
}
/**
* Updates the GeoJson
*
* @param features the GeoJSON {@link FeatureCollection}
*/
public void setGeoJson(FeatureCollection features) {
checkValidity();
setGeoJson(features.toJson());
}
/**
* Updates the url
*
* @param url the GeoJSON FeatureCollection url
*/
public void setUrl(String url) {
checkValidity();
nativeSetUrl(url);
}
/**
* Updates the GeoJson
*
* @param json the raw GeoJson FeatureCollection string
*/
public void setGeoJson(String json) {
checkValidity();
setRawJson(json);
}
protected void setRawJson(String geoJson) {
//Wrap the String in a map as an Object is expected by the
//style conversion template
HashMap<String, String> wrapper = new HashMap<>();
wrapper.put("data", geoJson);
nativeSetGeoJson(wrapper);
}
/**
* Updates the url
*
* @param url the GeoJSON FeatureCollection url
*/
public void setUrl(URL url) {
checkValidity();
setUrl(url.toExternalForm());
}
protected native void initialize(String layerId, Object options);
/**
* Updates the url
*
* @param url the GeoJSON FeatureCollection url
*/
public void setUrl(String url) {
checkValidity();
nativeSetUrl(url);
}
protected native void nativeSetUrl(String url);
protected void setRawJson(String geoJson) {
//Wrap the String in a map as an Object is expected by the
//style conversion template
HashMap<String, String> wrapper = new HashMap<>();
wrapper.put("data", geoJson);
nativeSetGeoJson(wrapper);
}
private native void nativeSetGeoJson(Object geoJson);
protected native void initialize(String layerId, Object options);
protected native void nativeSetUrl(String url);
private native void nativeSetGeoJson(Object geoJson);
@Override
protected native void finalize() throws Throwable;
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -5,7 +5,7 @@ package com.mapbox.mapboxsdk.style.sources;
*/
public class NoSuchSourceException extends Exception {
public NoSuchSourceException(String message) {
super(message);
}
public NoSuchSourceException(String message) {
super(message);
}
}

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