From d764e9829eab48d2b6122ce2285f5ed95a366c6f Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Thu, 14 Jan 2016 16:27:29 +0100
Subject: [PATCH 01/19] [android] #3450 - fix rotation when enabling user
location
---
.../src/main/java/com/mapbox/mapboxsdk/views/MapView.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index 5810e390f..ee74ab4d0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -139,6 +139,7 @@ public final class MapView extends FrameLayout {
private static final String STATE_DEFAULT_TRANSITION_DURATION = "defaultTransitionDuration";
private static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
private static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
+ private static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
private static final String STATE_COMPASS_ENABLED = "compassEnabled";
private static final String STATE_COMPASS_GRAVITY = "compassGravity";
private static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
@@ -973,6 +974,8 @@ public final class MapView extends FrameLayout {
//noinspection ResourceType
setMyLocationTrackingMode(savedInstanceState.getInt(STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
+ //noinspection ResourceType
+ setMyBearingTrackingMode(savedInstanceState.getInt(STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
}
// Force a check for an access token
@@ -1025,6 +1028,7 @@ public final class MapView extends FrameLayout {
outState.putLong(STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration());
outState.putBoolean(STATE_MY_LOCATION_ENABLED, isMyLocationEnabled());
outState.putInt(STATE_MY_LOCATION_TRACKING_MODE, mUserLocationView.getMyLocationTrackingMode());
+ outState.putInt(STATE_MY_BEARING_TRACKING_MODE, mUserLocationView.getMyBearingTrackingMode());
// Compass
LayoutParams compassParams = (LayoutParams) mCompassView.getLayoutParams();
From 3fa63fa5e8fb59daef86ad267d39c2b45e9b6a22 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Fri, 15 Jan 2016 09:04:35 +0100
Subject: [PATCH 02/19] [android] #3052 - update gradle to 2.10
---
platform/android/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform/android/build.gradle b/platform/android/build.gradle
index 2f5700c87..f3a1cc06b 100644
--- a/platform/android/build.gradle
+++ b/platform/android/build.gradle
@@ -22,5 +22,5 @@ allprojects {
}
task wrapper(type: Wrapper) {
- gradleVersion = '2.8'
+ gradleVersion = '2.10'
}
From e22b0270f486cbece252f7faec55cd927403200d Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Fri, 15 Jan 2016 08:51:44 +0100
Subject: [PATCH 03/19] [android] #3559 - don't show InfoWindow when marker is
invalid
---
.../main/java/com/mapbox/mapboxsdk/views/MapView.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index ee74ab4d0..af8113047 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -2704,8 +2704,9 @@ public final class MapView extends FrameLayout {
}
if (!handledDefaultClick) {
- // default behaviour show InfoWindow
- mInfoWindows.add(marker.showInfoWindow());
+ if (isInfoWindowValidForMarker(marker)) {
+ mInfoWindows.add(marker.showInfoWindow());
+ }
}
mSelectedMarkers.add(marker);
@@ -2746,6 +2747,10 @@ public final class MapView extends FrameLayout {
mSelectedMarkers.remove(marker);
}
+ private boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
+ return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
+ }
+
//
// Mapbox Core GL Camera
//
From 2631f5bf9358e386286129f984beda90c1b9010e Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Fri, 15 Jan 2016 13:14:13 +0100
Subject: [PATCH 04/19] [android] #3517 - recreating InfoWindow with correct
MapView instance
---
.../com/mapbox/mapboxsdk/annotations/InfoWindow.java | 4 +++-
.../java/com/mapbox/mapboxsdk/annotations/Marker.java | 10 ++++------
.../main/java/com/mapbox/mapboxsdk/views/MapView.java | 8 +++-----
3 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
index c74cf478d..65f89c48e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
@@ -194,9 +194,11 @@ public class InfoWindow {
*
* @param overlayItem the tapped overlay item
*/
- void adaptDefaultMarker(Marker overlayItem) {
+ void adaptDefaultMarker(Marker overlayItem, MapView mapView) {
View view = mView.get();
if (view != null) {
+ mMapView = new WeakReference<>(mapView);
+ overlayItem.setMapView(mapView);
String title = overlayItem.getTitle();
((TextView) view.findViewById(mTitleId /*R.id.title*/)).setText(title);
String snippet = overlayItem.getSnippet();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
index 8978d4be4..9482afaa2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
@@ -1,5 +1,6 @@
package com.mapbox.mapboxsdk.annotations;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
@@ -84,11 +85,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
*/
- public InfoWindow showInfoWindow() {
- if (getMapView() == null) {
- return null;
- }
-
+ public InfoWindow showInfoWindow(@NonNull MapView mapView) {
+ setMapView(mapView);
MapView.InfoWindowAdapter infoWindowAdapter = getMapView().getInfoWindowAdapter();
if (infoWindowAdapter != null) {
// end developer is using a custom InfoWindowAdapter
@@ -100,7 +98,7 @@ public final class Marker extends Annotation {
}
}
- getInfoWindow().adaptDefaultMarker(this);
+ getInfoWindow().adaptDefaultMarker(this, mapView);
return showInfoWindow(getInfoWindow());
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index af8113047..c475eccf1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -2705,7 +2705,7 @@ public final class MapView extends FrameLayout {
if (!handledDefaultClick) {
if (isInfoWindowValidForMarker(marker)) {
- mInfoWindows.add(marker.showInfoWindow());
+ mInfoWindows.add(marker.showInfoWindow(this));
}
}
@@ -2888,10 +2888,8 @@ public final class MapView extends FrameLayout {
for (Marker marker : mSelectedMarkers) {
if (marker.isInfoWindowShown()) {
- Marker temp = marker;
- temp.hideInfoWindow();
- temp.showInfoWindow();
- marker = temp;
+ marker.hideInfoWindow();
+ marker.showInfoWindow(this);
}
}
}
From a79ef8bcc3a4981975a5c78a47f022e26671186c Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Fri, 15 Jan 2016 17:35:44 +0100
Subject: [PATCH 05/19] [android] #3052 - upgrade gradle to 2.10
---
.../android/gradle/wrapper/gradle-wrapper.jar | Bin 52141 -> 53636 bytes
.../gradle/wrapper/gradle-wrapper.properties | 5 +-
platform/android/gradlew | 10 +-
platform/android/gradlew.bat | 180 +++++++++---------
4 files changed, 95 insertions(+), 100 deletions(-)
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.jar b/platform/android/gradle/wrapper/gradle-wrapper.jar
index 085a1cdc27db1185342f15a00441734e74fe3735..13372aef5e24af05341d49695ee84e5f9b594659 100644
GIT binary patch
delta 19154
zcmZ6yb8se6w>=!&wvCCciJeSr+cus|Y}>YN+sPB#wll$e^WOJX{px;y?Nz&WcUAA+
zU1yzjR@bC~2N!`O{gMTTfCB-6fdQdwOp#1LqD1^pTun(=76JhQQA_x#iUIcg;0y}#
z{|d4GQ&>&{@jr2z`oHm&>3?Dp9q8WwfF>j`XR!aKf+0@+o3e*2`fsWU69x?m^*`57
zBkD^efPsL#LxF%WCM7^%CH3_|C#fM}0Fvw!(S=dQ{%)SG1PKNP6c&E*e9X-mfSlaX
zgvq8)7;;7tL?hfd360J0bG>$W_0NdlMOpEi&cE0R-Ce13)$4^B)jL`Gvm%bc0itVW
zp34wIcK$@3>mZbrmznU|6-jfHF~0V&1%Zba?5IBWXB%kRy2s%x8eAP(qQw>NEU|4i
z1W|^1wzST~Yr4Hwf
zM9<}V`PzDoDjaF(ofd81cvD%B0=9fN;Z}ZhcmJxHaG3jWR%!5V2y03$QCa}fl^y=5
zt+=Yn46FS6QYj(Xm1rThj#|-Xu}|*5s~oFJtRN&gdn+K8V%c6EE(*N%_E~|?y7gCW
z+0**QL&QW_&^NIEQO9x7r8D#AP`xNchZrN3xmW7
z*HjsnRrnC|A1ao>>p_P3%lvtuBNJbYz*+>+Q3EACN#atRaSN`DLXspCUyab157AKs
zH8DvNC;eEAETt46M=Pw%I_^R#rG}W8D4Z(Yv$p4NuELPnAj&?SV8Z^>>Mw@%5bsHZY1mub~=`S%20Nxkl
zxJ8J%Yki$zh#qBd(ngHTD~t;d1yMSF4JH1LndHLMBQg4l{AM;$tVTOZX1Vv5&VqV%
zoH3)ClJq>ynzdi+OF>IZ%d)zS!{v2P&+E(1<_Fy?z}%fH%M|5+sqf4D#3%doZ}zRP
zf&SMAP%^@j6o8U1IGZ*~9YYoaFvtu9V+XYwohZZ0XCn%gWKROu
z9akyNz}q9s#meVv*UUVJg9c|$u^9i%fSY@GyaJgslHUh{yW-6u-r@2qddn2^sO-Ok
zW)2;K>rR@1RvtRPSI3tsXI47t&Tzmn-93tgU{6GkfM(9g76U5s(k5I09pOHy(K&?q
z#L26E~L9O?rFn3V%
z)%Q0C)85{d-`nLf=|Y|XAT3T^g9RXVr|v>wU$$=@qDR*Zdp|hEtERrXRdP{LsVW^A
zeiGJGWWI6VoX{6b(_|yeE7&KGCPvVPc+hU4=i6uCpXzJPQ%CCK?p3{6zjtfz2r>$G
zXz$yk2O`GUTySzZbT$`MxB*8?m$SGyY8*OTMYl^^>F~W(r4S-5{0GfM8h%w?j7`~
z;b&%`ZCivq;1N|{yOJgUK3F{9v4-8Gv?cO9aWQV;@{oh4W6ew_z5DsTet^AUJsOv>!m=x2t=Qxj
zKML}B0;Bg}@~vyx>IG|(9Gf0blmi*66fq1X!Zs`3bn%F5YZa7E4mH7sk$Wjxr`f0p
z{UkwI);(TBL_1kB->jp+%UQPjYeCx
zu4DXCNZV+8tyI-FwmUQ^(F&OA9P+Ad{fXZ>*&>c@&R^1&2DzcG3(|DT}-W5?GQYlo;_qrk$N!WkqWf`XTMKD0P
z&9xMa*^R<5Q&6UI`Gsyiecejat>F%f+{pduc*EL+A4!T4r(oCeS%S2JdvzI6f;E}B
zixAm+$Qs-2_5Tc+#P=+Iq&Zd3VLcn+0E^0)~HMr~T$#g^o#AjiY26P8+G
zrc41?J33vnl6!2*KbC%BOko6rJ8PuBcqZN|#WUXgZ@4P8MiP~*VT-VDWJN*Te<9Xx0_S?=B$5!FqFO~W*C_pom^
zm0~1rYHe&^RyajESbplZ&L~}cdERqNmExJA7rqmYLsCfqy
zshvyo5=D=xI!+eORW@hY|2p^nQ$5(F*8AH*^_^;`=d{_eOP7&
zyjuFqPxzSWAuV6LHWB7*rNvFHTm|F1ank3V6T{0sukZn&@ve~a
zdapPB;e%Nmf+Y`rKR&XyTWi+V78_Mxb89QOad76KO*zb(Faf<;S~N
z#yCBDStXIdG7RwhI6hN<&+-NQM0kmx+&%b`<5Qp!%k)5FIM9AdlFok^`m{^AAx%Fc
z0Z1N88e-lw(lfG|mgzC>6m(3?7YqsS17(dV8#w!y+!R!Aft^o!p)2+{EHjHm+l>}B
z0;S7pdT33uPhzS~ov!dP1v4Iu{iinD5!_hXes~Pq)ZGO2Y9#~eIYfZ4jm)K*%#2_s
zv_f(M^i;~s+yKk-V5sP|tHr67STX*}^UM?}$`O49L^Z}ptB#S<(8fx2dg;_*)(oYj
z$X}t^H`ODe=MS|j?ik~iZtgLh)<2IWA!Fhye8Y(~-e6PmFvf^a{I6C-Gn#%R%zse$
zRr3E7QhA3FDtQ1taKZrc7P115esvvkcE)fHzFj7d!hYZ{zUp$WWP=AyCnZm<5OXD
zv1pP#1%OEW=l}uWW0T}H`Kte8=WQ=DONb`aO>gg|SR%9_3HMk1c=!I9u5ZqRtS#45
z=jVIYc|yG8Oq=Bu^l`L>-Rtoi!f|7AMTxxpLpC5%1A>OYX_7zzplr21&KG!2PIXMs
zRF>LFRNazfHR^h5_
z%eh=1mf(CD`~`$yi
zH$L_b2A-;|?uSjFM8!?Lz4Ut!5_D;=qc((tRfcY&98qq@mCulqy6^S8pR|%y68(-Z
zcY~|8o;v{mhN+>6fY~B>B`!Cw$GC#Oq1GPwrOr=27QBxsn9Q0KvtSP|DP|CslX~qk
zO>?m+*)^t?N5(aARLW|l4~y=-*Qhi)-nnU^`x_&hK$vn!L1B5;Xd~jg^Tm`uu@NDn
zY(LACm=64HA&8Oe70wX67?*ce!Rb7dr}LPeOhXnRQD^0|cF)~=wWL9!!3JjeaZ+Tv
zlrzQ6wjNKrMiNLA$~MRSo`S6@7pU;;%|Ikdi|v%0sea)MYj`S~FKDF0x*9L)L7XJ%
zHaS|Hh1IJ6Vd^4tH?h?Kq3G$HLhhk!XclIyfPi^wTD7kc4cwl4EnH46D0q@jc=|(0
zkaZ2X%ug{9IVqQ=oJd>e!=E6+Uo4>mW|WyGV&Z1=fKpWG{HWk;Gyi*WpGx3eC<5xYb*
z4J#W6+Yj?6?en<=d~;57%=Cqh^9OMc-nIt704Y~&XLZFy%RqfpIr_d?B|c+C0J#&3
zwLdazmvEU1aSE!EAmq7BXJmTqs0NW=Cfu=S%&Q2G&8A{@;x%>bw5P(r7XCR^v(KFy
zA&uvKwuazO$m1XkOL_vX41FS!XXY5DI&L``uVbT!6b-^s*f3k9JW(IK_xafonV3?*
zB5u49(M%~?caAidN%2;JblZH5*h|*<@Jp6dibY?9F42>JZf^il!U+td)PRecxRAVV
zn7Oj-dlEY+Q<6=Ou!9ih%E^?8ObznaVNkDd=7u`a6XYX3eI-xIr<1Nx0CLH>+39N0{=b>>20UYEa9uE8jNkjQP(w
zKUZw?nUV}wt{vYej_McV|sAj-RvMk9l&BFcv*9TD3Q-z^4bwjrfFC#}8<
zlnCw>M;@xK>VMw!eBAGdL|XLNE7b)T5{WAXeMFFeux322xAB)+O42MF&!C8xF$b*VO|&j#}?$lq1B{6OfUtC#9z=nH>SLMQoV_#%A8!l?3BO@{quC)
zL2=V5v1*Bg;E3iKou6{$0?LY~-ZvHEb^XJVg{Xy5O)||(VCo?X1@SdOT`jq4T(aA?F<=^H!&edcW*d|=Fxu3;Xp4=N)|4j#g=na|;(aZp0g50=m
z3v#7X>+h6o@aJ{(pO)B0czfdMK8|wKg1lVxe+tUD*({BAOu(gz9)?Jpw
z4g@Uyz%-26z6dMyq`!;{qC@sMcc@iyYNxlVe+Q{f1gofF+auwe~y)A@C!VGoe*-9uU5O+?2R61+Y|rooF<
zqYtkLeW)=3_9%T&jIX`ae2sGs&yH00MdY)vyGGNL)pN-+KHI*pwa}L^tvLWpdE{x?
zJpPjk{)RZ<%xfsrJy+MfglpFB4Q(w?-SZr^^U7)QqoSvyka26zpu6$6q0R%r)^&pBz*2~)2>1P8GK41pnr2V5p(iAj4<_vu2gPTa73va3
zL27^=ta*=oU+@|_3Q^*`fTj!87aS5wLYl=)OSZpV7QLeV2e4~Le2+r7-XosZwC~b2
zewp%oJ^9J@;Mh5o)ScHc?yAUmp;%e4aK0qZ_~$u(5C-&c*Jfx8;yfmJ@=s8dCm9Xa
zGkg+&>|QSK&qKn!vcSm(@G%GM(yn5lLm%YV7?N-ip(~G}@SD~PTY#=7dM?+13|Gt=
z+3w)kCOfP*biq6SnIN1
zf!CV#Zqe>wD_{N0H&PYl$nDIA6O&*34)+Tnu(IDC?V<=-co`h`C18k{)Q76A)#y`k
zZ|`VDXPz2`HseZMenD9&M7z)~cF4o!j%W7hVwT^7llXSF%Xtg7
zn%N~ci)Ah61vXmPi-G@fEsFQ&gFVsqfOt8)V|C-{!e8+JpYkTd1P}Q?0YCotGPv6YsVfzobqMto{Jm0Vf{Z+zKyF|%-G
z;)Y#o?J9VEod^bwhK8KKb_gLJGTc0fKL
z^t3?1Y-b9WA$U5}6IMMmgyh*}9P%;crWo=$e)=%=?5p=B2|%8F6>WSl%J8EIzl(^mHt@@HCYZF27~9t6ND}Qbq?5Dox21Q*qL2F4`3@rlvN!TTVpR
z8k*$>)XrMQNs4@*{5l=yoI8o^o;hos-Nv8gxAAaoHW+x&>k;iLA`co82tgCzgFFZX
zma^1jsf#GmYo4U%HlR(!7Hsj()M@W+WJ)c5(}l4axxz3a-2kUC{0OHtfw=V4lM)3k
z-r4}gkrt<{27dG67YZtj>Pxoih*(&aDC*}}zfuXRCX=$q>sBw;Qgg~^4CLi27CAiE
z45Fr13c1)&ub%@WGw8V=<
z8L$Q0;=gBFLP-nUYWoYovM0Hym0>S^Ax{CAEiEYLCZ6@8zeSAPa<6m0So}7`$1LQj
zaC$~Zcsgx2mdZF(b`z!8_{P}COqb+nxC^{;ibzUy2#bb#(5jmgSWMvW_19oe5Trit
zT}F48TG|;GaX6Bu_xZh}6iWVWe-HUMplSmHBn_P
zRAO^gd3ivEL4wh0L=&6`EzRa-c(n;GZs~HKRM|w^o-MQWYP8DV7Rcw-9}k$--+xnN
zu)Aq%^E(1|NjG&H{R%{@(ubKUIyL3Tcj`=~%HKHrhj{fIJ-L$_(Nw%^>oEb%otz=q
z!C|lS>5jlmR~2sicsX2k&E2_0D~lP1aXf;wo3k+oHU600h{4?^Yiun6I`=~}y3u;s
zkrK~_$h5r@I;1@rOj;be?*JiXtu2*0J#B4`duslo1GjeRkvwrdqOo{$`O3E_$4@oR
z%kHcN>6kQ2cD9lOhuG*WHGTlS?L|t&IZaUkAKv$muD|1(ju3xUIKL_JImEr$6RtQ}
zC)#6DpBnFa$@()#lM!vZ`kx&zQ{Vm&qkbCjmmPS`V)PrfMV_|Y6ytpUdG~eFX^xDp
z|G_kUS}R9}o3{93F@3~Lucd}j5}dKE1d^`uTLxd?;m7U#O!M^u>#a4wL)irLN;=%o
zfUiI)MVX%sS;F5z%$8+v^M_D0`W~cWuavMk0Am>MSc^W6+R7gI!s&tPx?Z8ab
z_D5wUm0onmui)hOh3?slNU$AUzJ2vS={mx>8!74TOOQbQ!F8wLE`D^R{XD%?oc9^jA|Lv^B+2!_bpope7hyl)5wuCSwd!Lbu|J-oV0h
zqqeuP@3Cycvu5`xtbu}3<_wTf;C{u^4JH&T`qGI
zwr~e2387Q(Gt_1W!OT*&p!TeZadQq0d$og}sz^|m=mz*Wkv5*Sg7OE=Z$%xqBc!Pi
z35%eqa3(i#mPZOCA<#8gfH}~f`r$jX~tIey$jG%vIiM!yTh&|8K`PmVcceyA(Fy89ratceypYuR!K
zmbh@|Xm$BxSxg^H<7&I98zCVo9lMvFh1V#%iM7-9M6&XT|r_A0f)@63m)|<)Fjn
z$RcXlBG?_Ez}mT2JlbA-@?U_Zb;gTg^4A8yUur0yVJ@O2Sn?yRrcvc|#igx@9i3h!l%N%wU)!gg4|e4PLQ
z`0JkFzFtunr17>GFCCGh%3qSByrV5Yu!B<|R62zrm(`Vw!q-*D9KiRnz=t@Os+`4p
zCTE4tDO)^wY8&-DraLo*dat*>8-E+Xn)O%Id=Dz5+z0dRbym)2*lax#-n_H&7T
zUt3(0ta>43%}8}Fp_m_=O3}pStZqEjy`JI)U%}d?RIj;?$!Ytv{1Kbqy~70ndPA7i
zuvOiNi3h*;*hy&3w`Df|>XLNjpxb0EDwi|U#G&u7t$loShrmnee_(6I5qU&h>C
z#nX!9mnHxORSJV(CZS)GL4c)D5JBe)5N07&I2e`J8C@iaW6M>NB&RMw&hH*1p9d>R
z_aH{Gl*QMs<}OBzbFZmg_P>(!hXmxC5yzNLH6BnsYYV>au$|^M-ST`0KF$60btdYU
z`1Hf=bkZF55cAa-eih>fkPLK|Hc(XFk$ul<^4`GTGArMMtTqqqcd!Z
zP~=$XX!a|9;I-&(xDzKRF43}d!x3X_c&{CS*m?;0Ziw>}MhNTP5hE`A&jOBr;Fz(e
z?m_fH1Wj)A0quD%%6;=RfJ&lyPU21%f|}e@zrb&@p3jcUX01pau&*%1iK%W%6-`TS
z*I|YGO4}SEKTG!qJhjYG%kD_agmTw82Rv7RYl7wL>9=1{cC*ZMW9?&p3X@mp8m+6D
zE>qsDkHjn|P*R}i7jw^()cnh8ma~5$%k*9QLYLK}qm?o#5kwOrbskaa@1)aUb-)
zyZx^-ODwZ_+CQOofT(TGsfJHNxH#%GR^9Yq^P&xHCU2!EB@aT?`9IqPO}(rpJSV@b
zoTr~&@J*D%JS8Tb=kFMBHBvIGl|kYDlYb-=BnKS~er8GHYJcOGMR0gQmYmYZ}*CwYCAHUF}(NY=o2s=MZ0lt
zY}GL}dQJas2TZx_mGSzAV!PQ6s1xGXD@oRc>o``$%CA))a&FZYAu}y#_|XtDnY0b2
z#00OaHC|<(pTF_wFWkd-PkKMMOS;NUwIkP^dlEXFd8!QS6#C%b(ggd!g`Qr%m6QWQ
z4A``5j9ohw_`j$EJ>0s(RCssBpiw{7$8PU@2#F7n0leSgKvdu2L&Y~22;$3hR3Wpg
zQzK@>jZ!8BDSWD>=UCu2?zDuX`WQ7g_JD!wC+2BJ2l%Y0dI3o*ML+Lu$$r_J+}P=x
z$k^`iaR5W72`y2Qd<=)GW|Ju@th4_lffYt=uOmU=jCbjN7Wh%_U}`C}IFPZ|(jg?V
zaV+f=AP=Y`tp__0<0fLInvvL;B{o0U-1omw;N;=Js;KPV8!o?vq6@i9no+13JuI7{
zLt2v2_&tTVWsM1*O&{TMs=3f2+uN~vHdxZ=R7|?$E-+^wfOIpT|Sn;5Xia
z@fm)H$DEvW+9V-rECfcw)zU~y7G8UJk#pS%)9D5IP5lksX7;)-=rt|~ZK$~@8AuXb
zU;bo`U|MnZiN+rxeZIU70zQ`qTYdiiNlBgq|6Wyc$
z%-{6ESUyj8q$6s>*K2`2eeF7=dTX@lIpZB8z{d`gK9-l)$0AP<35qUS+Bu|kAsTM#
z*m(`9Y3nix`zMtTN_>9T;Ghs5?k9z*A@a#>GXnPthm7qR))2M(xyYr
z73NN{%n`P^Kp-PtXoTdW(cvME_JuA1=%4R~I}{Q>a39Ev(0e=Fqn1)G>71enB>%x-
zG-KckTPt9*gqQHfojRnanbh60p4(puK6d)6{a57tF_Qw=bDM?AlSHsnS-t8mpylFavDd2Miw3-)(
znq#dZ+yk{kYP3c8;PoqkYd?ByFaeW!u~y@<|J;_T^|7BZ
z9708m{$0^hH!H}>0xM_yUF6A%6N>kxPKaWzq4(Y1kDuOGqfOb&8HM4}?N3pVQ(G@m
z$s4(x+#{7Jsxw}Q(BYEa13jJ%KsTL{emD_Tf8nqB`#a~2%YC2zsfrs)6?zxh#wo3n
zFvuG0wfu0rJZY^+e<0pFhabK4>aZ>!{c2mfG?d##;KrCKnrR}Viv>o$UHMo^S$?0$
zUyZxkeP7?$%BUM)gdB=ec&gSOXTaf&goESTmFNGeRHVeV)tlu13axv@tFMHa8>(Wq
z9Vg7FGpvvh|Coe2sWms^kj`Nv${LU{em{%_V^kFQu;z^#3k(P4vH@{?~BDp{xo6
z^B==iKd#_tQi8S=vb4N9Gpi~yYa=Ur6Dx~S(wR0Z8r;7EiuF{p*?+D^0#FbT9FU~i
z0XzUlT#x+_GeWROuMDbiGJwr;LOp+cvCu|Xwz;T35kZ>s&s$4Y@TT9<{kV}^Q%|k`
zUa=?w!VqY0_NneTleV<&FIv^`nCjgleZ#`n+HReiPWSrJ#%nqrPD~{Sl(0^|ypL4N
z;!+D$juywL4v2?pMhBWwF?VxRAjA&!mZ)E=&
zGFg%q3<#UH%q&6wTP|fm1oK~H?LhR;GWwspMmzKVFPd~)g#2$V-{&3lf10i1X`h}9
z4FWQT3Iaj}l7u=+^G}sq2jFX9eoJhQFN!s&jm2(LsR6lD&3Hm7<~=K-4yoh`Hff!t
z9kt=mZO9bkEs__;BXneB3+6*gN+2^+{n(;@7qi1s38iwq-Ou7Xbl+*9^zyOc$*#1s
zFtMHP@VxS!`dV}>3VnZ!34y;c?9ZI9#R
zE8cAodx&}OuV&dzrQpvIQMccy>8}UkD>{1V)Sd7Xxi@1t%TxBuSC+q*k;q}kRG@ertb&<%c+48)&*Q`yHFwa_rjksK^of(`IV<5S0Ce0BU^rL?~
z*$NXnDpi}tD(I2Y@6Ktt(lP|r#Yu?+PNlOT$C)8E8kI+_wK>v!?MA(1;jP+S<#=E;
z2P6n7zJxJTR(k+i#!AChmar{yS^U7Is0GPFrVi$;2Y}zoIS?Cj5o#YNeKx&9n_bT#
zD`2oF@n=>lTrM3_-gEBGyfW&P;}Z5>Uc`GcTSL}DRTkUEp=snen<`i&NgkHeuP*q7
z_m;q<)#^S=+5OEGJSBdcZaaGDY4&Q}lS+!unCUD9WSh$OV$wY3<%J}a!j*loUbj}s
ziTfwu32<{0(Hsq7W+H1LK6=oqMgR6xs(v4Drcn-a
zQ{~=aEqi9o>sVZw2A3&SQ>_tut{$Sj$dj<1e+NeI>N?f=`@5B)JVjgJdYsedX(4L`
za=EGlXkV59o9yrF#1sw1Nz~=Y-XxK5y67+6yT(
z1b}>G2|C`x}!0Zn4F!R+Ic)jz36zWH&G`%_D
zVr%74$M{EZQ}59^hb3;zK2-2Yx|^4$SV)VB=)tE2twk
z7KMfo;{&L~FPmQ!a;K~H@`GyG#qo)E8n$^IG3po1h>}qDWIdri6bO=Cg}M3?QnAJ#
zjtsAYWO@y?<9P1DPVUFEed;&e9yznYEQ6<@G`{X^M}(g>yTTPoLNfpl)*~O5h!5r{
zz4``xrUU=(U<7?C=^}ooY|wS7eWPg7(6WUn$vc+sv2@ADEMMFGIZA@@z@#p@PKgwu&R?B9L9(bx0MGpe>%1<6s}?=bQ}fv|N^
zk%#n{8*k_c-#@)sYi^u*JJ;Qvg>F@MYm+&Brw#|-HiFw9Ig@9i1UwXH;;EQv7Bz&X
z^FtJV*>3LH7z)l7nH*I7SP&Ks&~Yk}jf)ZltmK0#dDFmR&3FLr=>$+tB>Zgb9>NNK
z6_ufR_6;JhWLWqL)i;ojOxUjDJ8L`}^NRHkw20=jl^i$RV2&ig81EK%FS_0IE6zSe
z_6NwCC-W7Bk>U>Ii!}f7@r8UZB)A{MrphYmb_
zUS_Y{5JquTQU~aH(oCO4ZO%f14JtHa^WT1Xzj@kMseb*_iOHAuV)cbUsqe1;iCGvN
z5^E{S+r=ezs$KR77@FNY%aFZ|;$Gfjf_uU8{+nn}x6zDl^jp4EsrM%}HUTx;55pYM
zA40UP)s{Ud$B*f+>3FW`;Dv?KoULLNwUmWK`S{|$6=MJr+cZSajpZ;X5(#F{y1ViH
ztg;`q)#iFu49*s)U#Z9kK
z0z;(l4BISTv2Fd2*&j@AH`fO=ervR)5I%kCa-zLcqOnC}qLk1s_kjOPAe!Jq=Kpv7
z-wmz&FG&a~X~wod0|6PO`?s$DBMIb5JrOVfcu&>k7Jd3h?xZAeiUg1#elp|dq({e~uFNcR$0zP#;D;t;hw=Et!pKl%LV(d|hCyPjb0Pmjw
zaY5pV(>lB_#)7~72a#Z#fk{6LxLPvD?MJ^tCjU3{frg%7pv^7G2YX2)&5Y0
zcYcw>1YXSha{k%VK>i;`Y)5R`hh#ZOcR0jx%U1kxz_mIc1<~yx+wm*JyBtQOG_T%J
zlAkUExy6JJ01!5t_l}Kx6h{{
z*d(UdV((6rH{^1pl7Fw8gXPjP`sk`X`N*N4?-Zjj(=?p
z9P6B9YiGv!lb4!R-
zV6z@2SBhz4k*{SlS&4LgV*@^8wpshc<^2^o)F*TX18v7Dn4~
z+t`tW4@Sx|E)D4%agf+Bm!VBq!doqDitMc6d@Af>bd-G9OPzwPn(=sqaAHRAyIMu+
zkl41spr)!Rk0ygx_mnP$*_{XPk`u$^EZCG*|te-b9tMCA=>`N<5yN#Xh
z*Bi%a?9A^P_G})RYI^sE<#g69T3uD@Sx%Oi`s3_$#`Im)d=n{=+MM~3n1!8vmGnWh04t(rMXRqLv~0T?vM_#2Hu33MFIf_THsnt3epBD9sMx!BPe
zI-*z%H+mQd(1)_=x|AiC>053IShAe(EqI;0t=bDMA}~ty)0iy~L`RK4YQ8+pqOkX2fowP?M41Zd|cFUX{
z&ZARQ9Yq5;!q{#qJ26;
z;jz1%)RqEZJfrJID3Il_-TP*KEa{NHtyNx-qISWIEskYEH@M0u1-tLI`;}18Z~KZBAequ
zkuG<`Jd;
zv~nc_j^L2+NQeXK*|ms>L$s@SmeLSxY#i=zp)vpm#}#|qZeF+(n9nqC2emEi!5X9Z
zpudcHdlflUn!0WjHP3B7kK8_$Kh%v*?EOpd6$AyE)3X5AW{k?|fbWb3-ovVUbI-na
zF+c2_rSza6Hc0p?VHD56?2c%M9zlpauPUQ5jQ@q;Qd`R}X7mH0H?`@zgH)b1cOLT^f+;ho*5
zc#y*>ABZKTtVs!M{-caGw+JF{5LW`6L+lw1AU}DebT@Vm-i!I9E?}774B4m0u3KCGhxCqwU}^zY5t-)m8t3Jl6HM{EkfZ&!$L>!ZpWL-Y^q%iXd7
zTN>J|NmX^6#ix3_lFc4ad{DvFsfdx7vFBlB_s9EfWq?NzB(>rm
z#f{U^w9C}oiXM&ffIPe&VWTrw#dC$<
zuDqXu>Km-H{>(HTewM=zn`q!hLvq9Bk{onm!wD_Sxi-hyjDX6D%G%s-Fb~#5xTkGY
zZ8DQMriQA%_Kh*%dP7t)6`3e4@!@pSSHlO}?ZH>+iDb;0l0o!OLhV)wjRsKaBFz#e
zT8^IvL5enVZ_5rk9&Eqo{I+^2>yt!;j#PYTV^1sD-}5^u
zl6*fuCsbzo>OPMhsfiUvhJA7BcFeDy<1JUy67rsB1O#=SSQKDQ3e@4EUnRm>9`1G4
zyE9CKz@3xzZGdh0vzib*$GP!&rktT<5rxSxX{ANe^VDUiH;p_ljVn
zcW>Cr>?!Sh0@EY#$}81Q3KSxe-rklaP$OP9A5nTnD6iYZR2fHOe+;d5)alj>p+$(t
zhUF3)l!iW`pFHABjRN@Ba#l>wx9>^(%nGt1Wgo=8~sx6eiTpJ_{%4q$43d9FaP4
znVd~4idkYcQq0M4oQBkI{5nJ5gFY`b5v>Rd3XCRbBQ}&UC(E~+f2`JYVNdtHzD%Z$
zen;ZOElug(tg$!CO#n}NF4Y_(2Zil>Te68PychoD{fHTfss#`VzR*wf!wY-EAb?(;
zGtr`Fv-*&%@z)g8;xyx3o5~Xu4@GYefAj|`me`p8;wvQAt*yFXH4jtQzR$b&2*Ico
zU%vJWP$HxomDsDov~Oj#HD#)6!)A2d)6F~LqKnD;oPkMSG#&|5s-kp5Mu#{X3|@(L
zRBL-wl=2Siiv-MTH3wyekINpGcuFuy+TRX8i7)pN{&h;w_zJ3IO!g5}`sVJSKX|2?
zKiG)9O}n#U=~x)D)DrT_j7@AyYu0}dsKMEas*6pvq>U+dITw6F$jZJcgAT{2f<~|A
zOp;tsV7M&Ntp{d#)868A%yVQ;ZuhVs;M{{8ibzpuhXQWF>Z^)iU31ZxN6iyaNP4=?
zNW<48k%4I}7B)FW<<3)+almmRyl2(O8jbTdx)?S4NVOjVB5}swFn=1a>-PQ*J>hf&
zS6q@j&4J^42pw}hs|c&CHyvFRiInQ|7Ntq7zN#pxXa)FK$%%Rq$BZnGU3eu
zDtr5vIsoS1@DxLKfua^f2h^XrgRlbZ_bA7&z+x&b-j02k-KhNoBHl}sn1A*~@B>-_
z_LkAh*Oz&Alq=8ySMguxuSZNb1x-~woMxyr<}fuUtDkSjy&^S?1BLMQ<*JOlvJ0I8
zu*&t%KHapP6Ot8I%$UDB36{cW>+-AV$(SL$MRCD8w*{q
zI~b9xL5$erN|{|DCd)Ak9e`Z
z{D7vyuoGyCTwS`{SY?pi81`7s1=V3sMm+`W1uSh@jra(_rWL)L3Y(rhqbs_WRD-&h
z7QTS&^%EN8c~^6cKUC!_jTo^qbWS02Ts}-(i9)UvUwe9?u8dQzq~4YkpBMS{f!)$f
zjw|JDN!1(3^}eJPlThsLm?g20;_7`>Gazrb6#ospGXbE;^+4`N5e3WuW5jRp9wrzkr#X*{_L;x1Ny}6
z2_;h%jt!KE1)#HDsaYhH1o9GUIEQ-zzG1yte)GDpkm1&)bdZ+Xg234Bb>hnq$bkP~
zgw%!3(K=pYu6!SXU+
z^#q^Ts+<^b$3B_=^F=g#%LL}v3<$3%7=%K{(@E%090_FpO{DF7wDe&H&cXw^LPe5+
z+?oN=H7%xt$W;BCcx7k~e~)Xy1O1Z&*2&OET#^ESUZvarfc6K=a!d6ma6gZ_euyLA
zGedu1&G={S+jI#xMS}}^Ph~wYY#e~NGbimeN#rGpdoTZ|)ed!)?hZWj0ig5M++5L}
zHVf&y0;ZnE0SbBPecl}!iP8JA;GABVHyd{Tqufb@#%2j*2^3_k8pH
zzTf@bN%F^hzg+!>?J?oJm;o0Xwm#MCUDCC()kHV)OUI>vSeBNwt2@~;@efaK^}{Li
z2PtwD4}D&@IA2a*VFnKD9S-2V>s|UY@lu-0Y=}B_x|oq;l@aSNAzC`F@m7=lGTk!8
zeW)`uyjE;V%|&0CQ({~jRCxAo_N$+Nb6(9)ZtWSPd7K0U#$aQX75fuK9~r0lko|RD
z!hNH@@eR#~+(j<~izog5@qcKsrgFN#(Tx_)DCFUIW<}vM>{_FJXkhtXjP{rc~
z^L7Q!x#Q9g+^CD&B0|g2to{x0yh$~dwO!v;SMATse?ihFr>*kC{roUEnXjFjE
z3TEs>sjz`SRiLBpuHa<~slo4*l%pF*mK~A50
zMKidt5Pz`!ja5mhKCLHheI}1_SIlqF-J6$xp*i8i+E>#@n7)r|Dzod#NRj?FwMW
z?a@fa(ZpiTBjFKYkBF_qTZ+rSJJN;L&2^bsF(p^tx788kduHjpgJNUXdkfzdSI;t2
zUwykSjnp{4{e>y
z##S%P4PQI-zNt82x53CEI}RECm`apk^x873Q)1=ku9l|6n(bqKqFXg?E>&Jyymf5v
zh`UDd7HQQxN?m*MhU?mU*z4FU(%4bm>SqQTO4}RFEtL;GsPK6%lSNOBUG$JUJ8x|lF>HM54B5i%?+~3u_D^b}
z>8y*>U6za6l^TiPRgyB59Q^95)4q_uH=bp2&TQmxzrKCKfe|alN=j!)pZ|l+`qbry
zm`2jO7;+ISmOj#ZuUTcmfkD5qEXp=(jGjeCdQ-Qx*kJu1zA
z|0S@w6pAJVqs_au!kAlCTSgE#SWWle3+`4``U>88?W?j8@Vshz1(+uLq=0v|?$#c0
zevZ(ILL%RovcR!LfivDk32pePfI&hSMk@iHj-XdirtXYvx#bt{STPvEhl|?}Q`f
z+w+OA{Rt@Ylu_<(_Y;DsLa+Sa(o*Y(ZCXYghK8+o46HD|)1FbpYAizr$a5-2>d~ezV65Zf=5En3X9{4>mr1C#V
zcz=4A#ZJBu0NrXWKR$^M^B)=ifY}9y46KLTUe;H$V9M
zuEktS7=02xaKjI=@XAik4+Ms-baWa<=YzA$AUF$89UMs`2-tS2gPK-3^y>qi69VQ7ry(?h7Z(pRKM&!PAz>|!&+iPv5FC|>ncApGJfh44BK#fj~h5e_WcDFjji
znk>4Vj3vs3*xWTiJQ*BrC!)#l2KH_?cJkX4XlI+Cqzqfru&dBAm)wIOpYC$tf<8$H
z3fC>c!)JnW9(7O%w=>Z!?>mgpVBD*8T(EsMB$}Y6{CR2Xf&ajo4?!>87&vuN0XIPw
z81#sM=1v8yfRRoL;eRE90{E*-1c$o>X)U@ag!XdyY!$%QT?S}cP{=vJfr?c4i1cu2
zlPY0h>fqzbY{Oty^+#d*XX>bcwy+aX0Tvy?pB7Fat_G5oKxU2fZsELV6vFUhRAl>^
z4mM-mZVExM9t6}_?DB3xY`y{I^>(XZyuTslz(FxukM{1bt$z=RFv$y!S_FL;!ID`Kt;BJNc`!126omYD9-Zfk6Jp-ncfP
z!vF*b2nhlRh%PZ63?oq<0T+<4X}2hd6l$KxDUZ)FlTSx?DwrRm^BtlMNJ%Y;9j{1G
zNmwU5b3!WWf_g3f%6~{DKs0y=9I;P?*lblklNL7|c6MrJM&QBoau?wD0picit0)+t
zjS$6^7W9N?qX>x2kh7AtYB4FBbjbDJa2}*|;29iy;sXgeNq-t=<^%9BBkI)VAW_Qi
z2s8?33Ubw)>*N@>+|4+@bhN6wNDF=(AQ*v1ALzPmK5bcq32N8kBadCa@^!6d)R^~T
z`(3W}^HeUHv%J?V3p9YF<|LYsbGwRwG?x%^mY`~O_t^R&RQ2~EOdYP>yzW4*VnbjI
z3(`*47yc^ep#9GFfe&boW1v1?WJ_uuXpYdgHQciE!cSII?JE1!p|QfhiMT;FN3Ze~
z(5pg`CpgF~qRrxM`eiuRoZIOVNmHO^t4xnRq1X@KZEnwA{1adRt=xnyPQ{((Nq09q
zl$tgRnm=ZNdFvA88TgTL2l`D(KAOljiG?&yGt0F8J$f8-o_?Q5&=7(YoZj%lG)nyz
z7;gs0&<&gK8jhYqME3Dfp1DWl`ogo3Rz@!yN#^u`CM|ZDM>D%%dE^bs36m0Laz|7y
z*;O;5G68{gq7hI77GDD^xWGGBfpi2BgXCZ2iG{-T<8md
z2`t+aHjy@nlMYnEu@C`_koqu@7Qqp+6~QbJ6*-Z6FcC9i107g94MeQHn6g^
z;7XeKC+vU2S;-gQ@)!&V2>bV=zzEccj!X>xH)OdnV*d@WDAR}gK35;Wf0s43&Fb(Q`BFX{d8GH
zW=P?Ng0ks&@P(DnVT0WDaDm(o7lkx^EbY;0@liH$$8K>Ye6vIj(0vp7-kZL?EUgW9
zADg@5{jl@g^V4JZzWE05%0{v=gBgfc%3<>2j1Bk@4z*75dWAAfi
zUWILjz{WwhgIO@NOUW;e((&ws<3ZcOE&>RVW4l4`*@Zk)c5z5jfU%FbPlR-e9<>nN
z9J;;QAl`3x>GR*jt91@MGlz6~Be=l*AmCfX$LI9=vccuS>Q(kRwI5RmnJ(OI-Yn6a
z5}bl(i(N-Y%GD8Tsg;^8yQ#gvUqZ(0<kb4jN3US@&vTCks>KaMqDS>z1onfjr7)*ibbR%~rh3Ak|
zKGav>(uXByMgo{pD|YQPS0!&$%ZqvDRjkK^h6t#9N)3ll{)e0oqQF1|nVxDa?Jw_@p?eRKgbBy1IJhT6VF
z!K`4%IOm7rDCwxm-c}d#f`TmDwd2zZZ8>vf1JxuMAbANhoY?U12a)hE{kK@bjV_!U
z6^X+MofPzAKIunXpab@_-`7J%ZqKDQGbT0%=hoT{IAyx>$N-Ev3isuRp4@*C?G>7y_jR?lrctq%S)XMoEVM?Q8*YglL(=a%X#o*O?pCKHqdOG9L@;STvW-Bfp2SfT+#BM`TLbCbbpfXLF?)-=dpFP|%0qUcQ
zMX36UMQG0LszTn-v`AzqKC+7qNiERFbhONMb5%!cE3FIAJVt%=OjfuLqRvfNw&X8d
zI2E<-Cnil->#BQ0Qa+!iUf@OEUh)Uyc
zbIc?T;exwx6k-2`O~aRzv}74W$ukN*c@~68U`hmrLY2VWg}^!j(|{FCjJepm#3?~;
zpMh+U^uYy?%rHl-6E$#IEw%b(IPe^A?OnLCfzAMTr)PzE**!g7bjz{skxo?Xnm22%
znH6s+Y7A9}mpBM2Edq-)o{9xEU2v6@KMpvGuSBBZgB2^}CzV+TS9n8}gZQz8r|`a1
za_LLfMC{!mXO2T;+r-WObHzKDK>7X8Aza
z>sivLL*7bC3^947`3A~oZZ}#29y+usv4h(@UpBRA*9hJZYtWyGucWHeS_c`v6`@eV
zB6AMN+fmX-(e5jMsF`Hp(fAeQKiNt-@2)#{av_-XeYIhBIHur+fAl<#DvSj~FV0N{
zlTz}_F}0h}cktBXhe}S8KFQ~(QX5{3U!?MNJod?AvDt}{@yqDm3kd7flP6hgsKc
zup6j|s$_Zd1+;HZQmb+@#e67I*(rr~N`oo@v!YICPXfti4Gu
zw+Vl|jnEub+II*~((|C%L|Ko=I-=Uy6)iVm^V;OYt47y{GIN%@J1!Km3LRAiQ@E)Q
zsD(G8^zg1_7g1e8apdOv2YG4?vL-(-_sUMzY3}T@%F%3eVQI9y)|H3)Hljr=hxr=X
zAHr2wuuF!`TEa@q%^-g3sw0%5^vpsd{7A%a7wl+VDx#0W?2@2r$?(*BOKc%*%%&!v70rB09y@R3ylmegGA>HE@
z(tG6z?*8&Df5Y!t*Yd^MQ3}k2JlA@Iy7f&eDn7WJabBZ}FJZ6_s5Mq+be~!nS%VXM
zGw_$gw4^AR{v}s?b?5cth1v&w2a|F^b$@gI1o3C7<)oN0?%+qI>Q~{>*`F^9(e`XJ
zOuhX=FGRB5FjKjqhBJyZ06tN7Ltn%#O)yTVG;M9ET%b)q%ANrFImCTGblXCO1w@f9
z9-_xs1G18AM^`5(kN5~kRC#DAdGrOEUoa;@=Mt5*LdWn0k%DL_8HnarF0IG
zpR~=wTALy~C6*LG?uHp9+lx)7DEMi`-St`>EabQD(~6sLSJs0eZn|xqa>!3tvCZIm
zr4w~19ivYn4h9Ap*L;5GBdvoItiNA^3)tw_>1ijoOcel&7pfYP?|s4tPFNj?k&|)V
zfqF%`#q#DKD6ZxrfMZrQBfOv=@D`Vb+97*Yf|}Q&4HhCDXQCBYfg|KVzrHkm(5mN(
zxAjOW0BstdkrI|N82lm&oEa{CNfsHs@}DU2hvP;ZT{*FD8IcEf9`&hx(Y9
z_rh8YS%W;c9q#go{YItP4$s>qC;(3bK&ZAe2>{U8zqXzw7{97L!aF$a
z#NS>#I`>f^M1Qd3W>DOcotxR7?a`q9BI&ly*xBAh`kr0VlQ5ew`!nIR*yjL>i#3Pj
zb=?>~uoLFqEGziHU~EA>o{t
zm2NNS2b)L^A7BUO=Hcj}%VmeO9%N3$S=J_07z(+Zh+GY9$SPPEJ}{pkVD8%uzQaLO
zV!O|p#u=s|5QAn#$s`ma;+AopgnP+wrQ9)DXh@4P;1r!s_RgmEm)Q8!1x(q8FE$=LqEJX&w=?-bOSGJ
z?(7+ge1Mh761Eq32VcmBTXN5($quY1pPqkYXZjOJLr>c_Oxqiq7kmcdfNhP4&W=y=
z*$~&px{aMLhW7yp8%_74RbDSJxLoAbonOQRZYD1}lJD6<^i4l@DDtp52F7M3mVQXx
zss+BJsDBI2H|H3jB2NtKGmSG1{NK$gk^h%ZK=dQ`FK$g*i7vqMc&R6b2G|+LnY9+f
zHEaE|=~A=;oy9K9XlEa3v7
zkm;3xemhxeB#D>zal|0H_I2#JLIl(Ju;Xs9)a6Gx=%@MERsy&T62Y!miMab--#p^~
zno4Q}u)u=t&TNJlWfjx<}*nh3r#v(Da<)={Bt{taQHSsna#O{
z?q~XK?>V_wUw8BKBHe}Cu-(q*9S*>*hl1bbI3xjxLk$Yd;R>T3dVghMS-rdi
zCL5hT%e|{U*mLACVlWd8E8^IA_Wjd5BSF*wzy~jCk2sw$X3rSehc{4yC%
z!Iw2kqHvAUBsb-ig&FUw|LCn&{CztkKcN^y50P{a)^O^rDbp2=k`KCmr(FoCx>ba^7@b);}ylK_nzhtydb=j?l>M7O@
zHP>3;uFvc*@Y_}~sMxYMur}-zvrfrtMPhoh(ny4bM!5A@q>6IY*iD>1>5AjJL!FjR
zZ^;`A_hqY#CdAY2a>c2ROHis5G%|GCG@BtyyZbTBPQ*c*8{&T3)F*
zh*=k-_fsnrmAcpF&?{r91$Rut;p;5fA3gRTEVbE1!*qg8%UZ8jXPAy{Y@)64TBFex
zy5{ulQ)ivnGdhKKEA^8Fw5XH%;vu$BD^gaCyKi-JRG;#>2>&SRKda{Fl1M$G1Mt;q
zdBrLjz{FsRjbThGI!IsOXb8!-^0Y=hO4Y%b%}b{qe&r8Ofujt*qZ`>>XpSOX*fKIr
zk3qj6$d+Ers5Wo0gww?b&Rnq3X_c1elC;U$ED7w8)zb7`Sz;dS5w+!_Vg+yg7H?d9
zzM(3G>iOn0rR47Ii?wUEMB%a-3xMq3lNZCFwy^f)rovsp9}C}BtJc8Rc@|1|D?&7B
z3^4y%V!6mqCy*B|kwHco9z;ByK|}%%%xw|8AE7$uLlOdmGYWb{SSk)GXDHrglA5XV
z=n1_4K+^A#yX{rwXdQT|*3I8&uZT)z4f-Olt}MP=j^5}j*X-8H!@=|{2bd&agaKbj
zri&`c5_OMksjsl$7VQaC`|Ry1Tg^>{(XKq(HeJwhOWLf6VC@lE77C{|-%TbiJn(+u
zkF31Bm1HuXwN0vJU`RIimBtYfJd7M2b4(W49WE0oh7(lpRl=T*L76KLEy
zZIvCI7Sse9X*N=*y$e(NQH6bP7UvgBb4`8HaJs#S08KsQaJtpuvVb~E3ohHFHDf`5
zThKc220?0^qJpeP=-+pzmUTRMCV4@8DU1*pU(KzL>?T#2mux(k1_ZQ=-r|%*bj8tE
z%P-Xw#7|4+heWEo1-lj>Fuc%o`kJGo*zr+Hc^&QUROo<@7Lt8zUssJh?pS`?Q-sV{
zy5r#GhZHw0Rl6O7eh6u8o@QnkVkyQTSantvtH78&OZnj;(_Fvool{KbNS9j9OQo~9
zfJ~UZ1ncD!8$UfV3V3QOR!HwGuQSMKk9l!WH(xs(4m8hrWY=THH$VQOp9^((6SyOw
zx<&HB@Pt`VyD!7}S$?4Z;*RyHbf;fl<-3MHl1TkADo7bou|)ZRW`o0eD8HJ=^~2=d
z$~U*NC2n=m$SxED%xnhFjkZSRmsH$_1m*MFLS4QKA^fY`EP(f;(yV5`{%Y1b*|A4u
z7~H(QyCCJOvT~b7bzmf@SNZ3RL!>}kIy?B2eTBYiSr0pAt2#ega7F%ir{n|EQfqkC
zWko2G8Vq7nKicX}T(T=S(i>)R*pCqJgLrhG$f0nCjCrZaEfuebWhGf^zH%8c`Xuj|
z*z&BaA3qmxD**4zcGU5uTT@br0l?+WawJ1gmNPO6Lia^>QnjXv4nypx1zr1=;LmBT
z>c(@8D*ar3<=crF$qThq-`kt?4AqA({2bNpxf#&T>wU;tA$oeV;Gj8)1kbCe40Rme
zQ(*_w$m_3o&9d1NFF@Dh+smb@5+nDgjP}=C`GXARm1-gHCV;ah1e1
zR&hsOYpr@CPsu$`=en^kE7Q8AJ{M}=#!V-0(zaS>rf62vJyD(YB(rDxoyYHZYap0%
zb^9W;D2*G-uw{l$rioZ1H|nvc>@$U4>PX!oM_-SCwQqf5WOV5*Vh~eE-fAYm6Jxv^b5ByHRwS;nQwK
zJWHfe-H?LUyw%Rb6yz15Cpuq>*MA`T6L|>5R$?wrl0e89H@XA==jO(Zh{}N;!K}eJ
zYYKO6y(zPt@hhCV?4hcA?fSOP`DOOWb@ui3a5kWuWvg55dMABm=evl79;Oqoz~)nz
z9Irk>hS22T^V~t>QS#vYQ#)+w7~m_?fEDe4r^V1K+$}gKJZ8cP$(Onmeau3{3#bP#
z-5~g*-Xs+I{^_-Eops~==O82wEGfdH@)IN&X?;aOYugBJ5f5bH%7;GC5f3lZ9M}@j
zdZ7RxrgtMG^Ib=F&U48%wabU>E7ame#%oZe$r)TwZv2Z>!R&&>Kt3i}IeM{#&
zC{z84oFm;^;3GAUI%T=foA)?-;Bzt#9=-+$Sz?SfAEG~q`&Rv=j>%K$ieCA&V+9&!
zsVj_(OLedi@MDd|dix87YI(gPZFeQa
zMntg-XXX^;~^NM1OA
zl>;A)d@W@ma&l{1*odDI@xBgMU};{ul0(X8%>#Z&3csQ@1zPunBj8I*}{
zIvT#q@a223?nBOM{mmW$qr2yKt1tin+e0(|$p*>;Y{Z{O-hg3OGG2Y1p{m8?wm=r83z3)S0p{e`a_u`g6p1{adK?DzGb76Bp
zFR~ZF2Ey4x!E_~22=&9fiAt;vEQ8l{F@B~$GM^hS+=w7S@^YR9;fC>gtU)p$0B#Q$XJb6>pkia0PbpDD
z#(@&c5Vya1=HDM+F&yZ@HME=zI%XNf=!FtvRTn#FoJE<~#E
z@?8xc;#K1+)GcEZ8u}~*mGXLQ1et@q4@T$}W-5sZ6p^)9cTm?6Iq71n4`g7UxHbx6
zUko)BZP#dl03w}fWN;Wv_?sUUMx-Y{q8>|R&q6{0VNIZ{~g%s6+vo@oSvBd}|n}Nq6WyKlT!$?AK;nzs=QKX}B(%Q7q9W
zi7#@CUH1$=C*|rLHl;|`MNR11W`21APUU-18d1PXbPVZky5+Alv(~iA958~eN^8~*
zwgya?H1L2?+Y^S}iqompFS}VW2gr%Vy7scPq>nJsSdbak!biMKD@VC-Kb%u
zED{rFyHkl+83MRNj%h-Caa|mQ1JV!DG1k?IL~3ohX#O=o}DtXH;Gvq(qVDJ!R9R7&ik9l64_n_kE9IGfkKvQrp*r+*qD
zFRcW5MU?Op$4*Vnh{3V#rK&5-BWzpXT8sXK@9gt9x#}j$6{&B&yb#pz%4>P4R08lP
z%8VK-O1YI&jE9(*gyKy-!LhJnrY-(x3y9AAd`6vKPbxL{o_HAH8a&|XZ#U{#LN?3K
z=&=fX^jj6W|M{u}WKlI6^T=u!|Q0IW6`nUPW;Q&uT3JEp1r^w-PM^wi;FV1q&yP
zMw2*N1V&Hf96ce$fK-WN-M?!`K^5@(rQ!}KqhBAv3_mXq9nR>ve&WCN;c>=@ZA76L~dxWI(B^OlD9Z!gL5}$^|TvT#^4o^NnGE^lRYJ
zhAvygVdI-V?|Cmx(nx~e53Yb>t>JsqFXSmnBTfs_hX@jS{atgesvSs9S=)g1ToIOl
z3VM`kB#Q*FTD7J$B8wRLs!od-)
zY0{oa(jGaSm~+9Cs#BS&6T5&rB0EEx58+D6QFf&e_Ij8rBSP*WrAs7sw+NOqH1m3z
zMY!$9Xulkr7RAB#v5J@zVyhs5^6r)bbd*++7B!FqsFrxuy}B|nof2UCeQNGHeERz?
zC>}{_L-Uq#JS~b>-*22Kj&83y(8fcS99DMmmct7MI05xqUd^nq1`Cw%^V`_J=r6~k
zyz3cAFT@eaKyTyK>6m)~!2c_e1gJs$TQv}=p$Y}{Pt^dzFIAYtQ+-K9898M}Rux9Z
zMrPI~<~r3xegkHBh2H>r*;}TG-z7KLiM|Fz00kcVK_aA`n_5*NULy;L6uaaK+UgE<
zb51-GPz-}gfnNEF(QKeaT5i
zfM++4Wm0S|2)PMJA(N(gJ+N??Ac64yvck9%sMH0o5z&=J@-@}@*&*p{qL$exna(6T
zP0*R>y$D=C72A3fnl!`rFd51#A6URp*T?lnFNYwW0j
zt?K7<=iv4hxXp76hm8rDio!e8H6adJAYj-Qn8&
znd3bB4e)*%3xIHd>s^i;YKVxnf--Ce)k;#UviRne35bBv5!u?Tay#(k%q|;1kIjf+
zLuar!8)*oo*F7KN#zSXtJ1~Cnz+)))&?;P~V7=_8Q1g)%fthsl(XPr3KWsGe6|?A~
zrWIHXpB+TrWPpOySH085tF^}JOXa>Z^$|PsQRCfFyekQ`^ImSglztj|tGdukMo}n9
ziDo0!2RK(d`E6*@QJ$qWOQR1~bCm=(R@;wu*{+u*-RA@iBwZ!llZ{fQOurkgPY76Y
zsx^8n=xH%g4^ved4*9zJe0e@|0uJn)iOUfF9bkxBlkqW}UTEpdXr%0!-}Y#VZY
zX5pT=o}`AJ1JQzKdq~Z0rbg?o+utLbIDozC0*DG}(8A)cC30Gz&mhq%NH4FZO`Bmk
z$POGz>b6Ll#f>5R@nIMy!6X6|(vk)vyy73YQ*vp-xa#&Iub=$r2}U(`ne_Fb&Nov;
z$2PEu^g2Nee$Mtm;p=iuY9+@vV(@WwoE41=RXoHw!cK3m0@{!~tIIKURod%~r;qDt
zH~=KN5TM7b^F*}xCD<0aASja11iSJrM@^v&=Gyw&YFaJMiiK0DaY9TbNxiwEl&(~o
z?zo`L2C1tL0e`dJ&Y%ZhM!b1P!JFj@XK+fqbVk&)yC&r~$8ajusmqQ@)-K%KX_Hzq
z#n!mhHZ*Qv3clWlxtYg{gU5n(I!sr!1jxU9?|4j-eO^i-PAF@Ye!$||a%+S4|0-Tj
z$(O@1!RCxxvz|H6cH;~AbP+6oo9F$k_bIUVJ*M5LHvP#X$Tol0>?)(tBBy1@
zR=%a35LxQN1Is>sPA-8w`a6mM26qh6>W@H?uMz}^lxvNzMgxvfuKm?9kaq;=`hdkd
zS09mK4p$#o4cD${dm71II#Ud5^Wd`=gr3R+?{_$Ti7M$)6Px5j?*E$LucpY2UCxqGE}U?SWzd(ilVePOQeaJbZdHHSf*
zwTGB5WTVcD-KQax*vDQFr8Tq}{D6~R1SOAi2CkG}>$hFzyJU-ok(JWG(R&vh;c>bB
zqG7rHf?%&iTk4C5vXGAznr885)F(f6>q)h*#TU(K=lv#t$B0=(2#Vcz_9VsZv>}@$
zzI?Ul%8N!`TtpfBSzK3noM$?FVvNKUA8Wpm-I@z#hSX`pLj&Qzk9K^~9_h94Fb6=>krEYGpw%ositIUMek
z?mU5upX5jgFe85j<%|k$+a#jC7RK7o(deib7~#8dH2y?ltwB8OPTGZ}{Pmc3e{_5)
zN4dTUHN7kP!cBr!h-SQ+uMCJ%xoktY8l!WePMg^dtl6WUQC=(Ft3AtTkGA`MNf3?K
z9gw3VNr@F*QqZHPEvf7{YeDxYvvS+`&E`Wu=`yr
zN0jh~VchKVA%X0Ho+hV1=3FeMBN78~v_u)76c`4eH@3hZ%Zw?Qi5D;d03r|f$x1=~
zK=-Jpz#uhb5t(lWuljie&!mlqx4I
zQxjdg5neqve+c@b(JPdqfSPZel*7S6UQzn-97)0~TU?HscLLxtVrnEcn-?#N7^$1b
z1Mb|mm-vRE5&xYrdwX@M)Awm-n
zfk@c=yeSqs-2VWg822mNmZUk>L)+Sd+QE@B=w}$^o%7*g?ShQv**Dk$lN&^)_UrSl
z-MUY9h!fNx#kP>au+cd%=_1Cvo_u~}Jc*rA*q>Gr8$Uk^IIoQjEdYd_9?TVyZ~At7VJ6kgh)
zqe5;;wY(bk+mcwM>r@iQMF46Nevn4ZyB5#0JJ-AI_+nf23G&~x-#8mF_cv=Z+i0{%
z|1S6i`<;fx|77jaDYC}bC{>U@xt9|9tC}hb5KuYwzZn|)cY&qqa{Fh`l#{s~JrW5p
zgceDp37J0%kxl5ghy);reyDG$N95RPQ^D!bNFmhH)!L~Q=-?N6#Vs|I&`c4{uC*&I
z8&|INzO}Q@dbYdXSJoF72o#QmHG2i2*`C8Wc)?;aKB9-gAw0
z$QN?ymx8df66C8O$4;Fp>Bh|#wkz_NTJVaO;U4p0@86(&s2x;_LMCrk5uSssE<^r
z;LMKxB;(E|
zRoARo^ki-fPPOz&k;jA@)aEDcn;fQgWp;M+cblN6IdYDfIlcE>&?&!reQnBNfV!oQ
zz9`-#0_fBr+~UN0+xjyk?MCC&E}kGZ?e<>4>4c6l$Gfw18|;C)(n)vLGkcGvhQLxFWN}*P+N7Yq*mS)>{}e
z6U4ME4|8)*x1~o7vmvm^m9wC(Ojry=kPnRC0_15@zm@mtWw+bmF1|z-Y!=pkRq}R<
z##Ye08!1X}V%>?sXW$&y4Yq8WbbwS*^5u;0TlryQ+a)I_l)AA}gx)HFiX)LeQWoz#
za3|VOZ%uRbow1P4pl-`5dbs-cx0SIa=+ZUwq54Wsw(P4Gs3aWeqPA>lm0qLW@%Kqwauw)Gc^rnyz&Sg+m-7IHZv4uF-)fDi1h*b8~Hn|WTCJ2
zZh_=$Say*a<29VDy77FSYaiH5g|=$!L1L9gcP$kyZR;rY6&a-a)Do>~`(>uEofcFc
zG3=!AYc+4Tc9p|Sn5g<7@Jk*ky^JbrMgZ55YBQBrkWN95wYeQ0yh>#e+yg_npeL$D
zvZMp6^Y#7Ub~dB_gOA~T3(oeWaTVo`oN*mY>v~bGZ_9Jb^~({psKPeQ)GIdPE17q7
z?`{y?<3AXO(%zsu)^p;oWEPybNXGrZ+k<3#ieFkyY@iTcrvab>
z_4Tm0c}Ef3)9TbjhRxt)*s3(d;TD`-S8!x?hYTewVND~CLhGRPel#0_Q30JABuz%;
zFX)q<-xw@w*F~M{*iSC6m_kJKJh+)@NlB9V$KJ%w_ifma-Lu;x+S``pJipSp-21G|
zRhZN8vGY`P@TkNepTMUUB_wIF*#I^SJ)I{6AwUAMB&CQE8};n
z2jR^)*!5Tl!g#uoX(G&Aoat?RoZh(R5)d$eqlIWu*3VWf$m;i^F5`y>2N}9m7*7j=
z*C8lEnfX*U*TbP&8)3rjhZ>N)WNCMdhE=3YVk0#DTh)&vmL!EjH7f_8;{i*J+utE<
zE?G&xt}U61B|5%#577>ID52m9Z*VM<16s95s7F}QC!D7YPe^(!*IfViNu?>)N$9D0*W;}y+
zsT9&L;z=Vf@~FL*c5@>$RGGZ2Yn|gXoO|Z7oFl#-2qTD_-3A&02A^d?y;4M>=!uNN
zxncFdykS2h_DU-EC`&XzGB>Fk*@n=c(fEesebks*?lp!w+gy~qoIC#_9aMYZi=%IQ
z%ht8KH+$dg-?ml9`~q2=C7VPkMi@@eGKJWk(MK!bf#dIU2dQ1|lAWZ*M*|%57$;|%Cliyh
z#IdSb)O;H?b_}{f$sdK6UvnrDb4t%&72-F!-F_zvxg&I!*=#rJukxy5Y7-g}V|a&uYMb
z;0UBFEcQQ~xmA+kr#^&@^FDu=-5$P+rcgKEwXM^YhKwkXFj7arzk&Z+*ef0KS9m}U
z%H5}6^;^lyy#*)*c{`<)A|eHOlO1%ips*BZ1(**u_K&`32mO5EvSAkSEGG;|qNGm&
zhY(=E=3K%5#^xt<7F)
zp3;KYmTk3ohY#uWt(UF@Eq%bb*k_sib(R|<Tv!|r}L6sNKmohG@4t@
zao-&66LZZ)NRR|@-<4TG|3#9z}GoLH~VBQg}K%+j_Uj?OoVp^@v!Fj>-}mT4k;ArmbnVT(=vaQwM2X
zA`au;a{3m3WQ`pPs>z}8x2Dk(4)};
z_ZU@AJiE6eS~v_CP-goAjkCAX&W
zxF52iriD_L^2<)%*Q(f2Ucp|3I?fa+e{nK$(~Mq8q{Od7S>Qg}(9Gi@mg+rnAEz4y
zM9PI)l6|^W>ZF?=^_g^2t=vfo4ln>e85LN7toe2SiaC&2MIii1X0nG)!~z!T|1mTS&`HLQI2+OB$uBu9I1JLsJm4e&%j@*IfF{QsECqX%THE1Hve@+6m9M3
zDne+W8n#e}{9+}RSxt+(K6!B^7OBg*TKW<_u}2QT1Sx6K40qVFlG1Mj1MXnVXCu{J
zhJQy**g0k(biujGBPY3E1S?ONpG*Ycax-n0ytN(*&|g#l1e-&gQYomh7*d7b3Ba{=
zr|*8D_|XwFcwy09Q0Olr-#;g;$OM$42YKHv&!f;4#=Br_N9GtNF8aC%#2Y>N4_cvW
zLSGFv=)nYL?<~o@N{k29%&YFmkj9`O-qL}w%{%#E2I}BvOPkYt7~2vc0L}s1Qiw)j
zzK=-0*v>6;o)OfV>V8q;Kjz9x7i@k>cP(RA1zM^Ld8HBbzZ*V^UDWP@oX8-+gL@U^Z4N70
zei8W~$Uq3>BTCDMG7Iqmm+?A#wCa`90*go&t_*2H^7CX+v6iVj)1{?WiDq(T7M56B%H0e
z%m+tDQ6NB9kSGJ$jb;T9?DIvltI&OwK3&AnmPm~c2W(o>xT>&xm7;SY)f%f)7uCY$
zlev0C2|4F!iuQx4c%~92RD#UTqm0eNiY=7S5#?!1JJ6Mu%2D{bCCTGSdUasCG@b3j
zbyH090Z(
zc=085Nn*DDpGtVCid;1n!TYNWB8JXNAME@X73Hb8XU)GAU34s*iJkg+U5_O5AVb<#p`9;~;g@
zCTphb8&)2MbnkV*em!7*of^PSNDm<~8ZM&u9CZ_*lnnXyfg>`7mJsg`zu&)MBT~=N
zqv-ObCd>(ji9@n8&(uP)fki*8Z~gQ(RDO)%PJFXpXtjy-P!A%UOWM6IH3j)F2j;g1
zuAI#D4|MGYxVVX!;^_ah0GFLtIPG&eUGbnvX0!4)jN#i!$T3Fhoj&0;Y(%j^Lm@ew
zRbXldl2s>eWXqIcM007YO3eYC@9>vwe)h}2foU_8C0q_#H_TvW?vTOXpp$Rjm4cV~m_}m3bFQyMA4w@uDL~>tQk^>XE3&PNl#I{g!@vEfD
zc*9R3z_MfTPA^fPUnt`n(Ehzn@SHvpE8(I})#9fAki9c-_n`TL`wQ(G{p$R4TlCKH
z*GGa~VSzo3Gl_TZUunA_sc2pJg2T5d{^(!94N~IZjcz2)ZEsiVeqKG=dO_~L0?R?J
z@rAGNk~H;Js#gV6Ng!SORS@GA_^fRz?v>t|0Fp5zfTL~wf8NY{W9h)gSjh%*Cu5xX
z=KA@^A>L0uio78w5Dm>P#1aRDo!oE7{ZPLbZp1vJpq~C>IU{O4`MTJYB>-Bs;r$EG
zm_3$bfpt;kgFT@A|wsAE3Nf1=YaMkcq3+
zra*qx9ZeWZYDK$WG{10NVDoSM`C}&Z4e`r&AnU68hMnFJZ^uC0_njrk&uHHC3!C#l
zMEoz2-=aYquIi#Je7m}O4qlWMnp?+s&H+LjYD!1hI)^G_-<_@E6$P5v(ObBn_pEuv
zue#C1LrA51=-7Js+&`eihM4jB(D;t#hMX*acmuDkJ})MaQ}KD1H}(hzD3JRp)X0`L
zXpA3MOA`0}L%&H`Xv
z=ASw)73KNDNk@@>Pn#BjfNDC;@6{0MgmmlC73#!<9DqV!)yoQ9T%7acg})lbx9G+G
zNX{Cgfg)1**yO^moQp6Y8rT_i`hNL6%6VSmlN7H01#s?8AIaA)*75UTxAQuSqbvI}
z_G7OhEv%m9@@e$3xJ-K*Nscqb?Gd1er+LjMt2fJ{s-DIvK5kBV-&8>i5fN;4H0Ja8
zQRMaprA3Fu7181F6}5jxq!U-8#jYu}@N3Kum?rPJYw+0Fyl&-JN64#(?=EZ`){Okv
zSAI>oV%~Hok#l|sSFRSd&nNTn76OQGxbr(;9Zz^g?!Wp0|5Kw34)hOm)cBr%`!4}?
zTeSPHv{>2<_Ln<~ssaK1LrS&u)j6mAp5ChXT|M#-DMg)#GmFuNTcDo#K!JcJpn-sR{>+laPJ<`H&7(KwbV-0h{WGGOR>a7}
zt6tInFQHh+%&wX!*hl?$-Mw8O%YPU1C)V__{XKNrNB>vA?*CV#+|Tz{lh`l!S2*go
z`zxpq$o>^d1~mQ(z=L1^^!)!;?vM
zZkqy53IBkvhOqy7gBivF;br)v;~6IZH81)rEd^5qXW
z!B`p>8wvdNhG!PP@M*m)^f5>CS-yr$l8|i<*0PVy(eX>NY-@t!@
z;{TDzzlVYKA0U!WV#p}@pU_LJ9mN4b(oLKk#s9m1`FmeLH*vodJ8{MkCy{3i?yp{E
z3_;;#;N90#P$DDiHFDp7Hq`
zfA=uK`;Ys|N&G*({trp~zk7}KP0XkwNrag~`8#%^ssA%6roSzd?{?XMLKdtUWe^}BDpZa#j*z^G2W;_k3u)
zuucARRtQ{1Rj54*NdO*pAjJ(TTw>2EOtwE~0nt%?PKs&yGNAkQ;30xiqM^8T?Mk50
zun0OY#k61zI5^jD;)i?G`J&jfSHPgG0a|5)qM2bGP_gplYv-Y9i1C6Hlgp;bvKQRJ
zA*3ss(Zmjn+1)^Q8lh+u-vZXCyGwAg!6`^^qLh{>iu1MsL&O%Gk6>k{8&H7@5X++|
QWZ5;@_o5+N`!0|u0Eye;x&QzG
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties
index 426759170..8f7944df8 100644
--- a/platform/android/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,6 @@
-#Thu Nov 05 15:43:10 CST 2015
+#Fri Jan 15 17:23:43 CET 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip
-distributionSha256Sum=a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
diff --git a/platform/android/gradlew b/platform/android/gradlew
index 91a7e269e..9d82f7891 100755
--- a/platform/android/gradlew
+++ b/platform/android/gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -114,6 +109,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/platform/android/gradlew.bat b/platform/android/gradlew.bat
index 8a0b282aa..aec99730b 100644
--- a/platform/android/gradlew.bat
+++ b/platform/android/gradlew.bat
@@ -1,90 +1,90 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
From 300d908bfc8bcaad777ba632c7e0c918b142670d Mon Sep 17 00:00:00 2001
From: Brad Leege
Date: Fri, 15 Jan 2016 12:23:09 -0600
Subject: [PATCH 06/19] [android] #3052 Adding distributionSha256Sum
---
platform/android/gradle/wrapper/gradle-wrapper.properties | 1 +
1 file changed, 1 insertion(+)
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties
index 8f7944df8..02ccb5a55 100644
--- a/platform/android/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/gradle/wrapper/gradle-wrapper.properties
@@ -4,3 +4,4 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
+distributionSha256Sum=a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb
From 2dae355cbd7097cb8adbc34e2cdf51db789b6739 Mon Sep 17 00:00:00 2001
From: Brad Leege
Date: Fri, 15 Jan 2016 12:46:16 -0600
Subject: [PATCH 07/19] [android] #3052 - Generating actual SHA for 2.10 zip
file
---
platform/android/gradle/wrapper/gradle-wrapper.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties
index 02ccb5a55..b4ada9d74 100644
--- a/platform/android/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/gradle/wrapper/gradle-wrapper.properties
@@ -4,4 +4,4 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
-distributionSha256Sum=a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb
+distributionSha256Sum=66406247f745fc6f05ab382d3f8d3e120c339f34ef54b86f6dc5f6efc18fbb13
From 74a9c505f9e390ec25fc16904c432dd19cc900f2 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Mon, 18 Jan 2016 09:10:17 +0100
Subject: [PATCH 08/19] [android] #3573 - Marker clicks stop working after
orientation change
---
.../mapboxsdk/annotations/InfoWindow.java | 68 +++++--------------
.../mapbox/mapboxsdk/annotations/Marker.java | 8 +--
2 files changed, 22 insertions(+), 54 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
index 65f89c48e..2ace201c9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
@@ -1,8 +1,8 @@
package com.mapbox.mapboxsdk.annotations;
-import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
+import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -31,18 +31,12 @@ public class InfoWindow {
private boolean mIsVisible;
protected WeakReference mView;
- static int mTitleId = 0;
- static int mDescriptionId = 0;
- static int mSubDescriptionId = 0;
- static int mImageId = 0;
+ @LayoutRes
+ private int mLayoutRes;
InfoWindow(int layoutResId, MapView mapView) {
+ mLayoutRes = layoutResId;
View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
-
- if (mTitleId == 0) {
- setResIds(mapView.getContext());
- }
-
initialize(view, mapView);
}
@@ -86,7 +80,7 @@ public class InfoWindow {
* This allows to offset the view from the object position.
* @return this infowindow
*/
- InfoWindow open(Marker boundMarker, LatLng position, int offsetX, int offsetY) {
+ 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);
@@ -99,21 +93,21 @@ public class InfoWindow {
mMarkerHeightOffset = -view.getMeasuredHeight() + offsetY;
// Calculate default Android x,y coordinate
- mCoordinates = mMapView.get().toScreenLocation(position);
+ mCoordinates = mapView.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 = mMapView.get().getContext().getResources();
+ 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 = mMapView.get().getRight();
- final float mapLeft = mMapView.get().getLeft();
+ final float mapRight = mapView.getRight();
+ final float mapLeft = mapView.getLeft();
float marginHorizontal = resources.getDimension(R.dimen.infowindow_margin);
float tipViewOffset = resources.getDimension(R.dimen.infowindow_tipview_width) / 2;
@@ -164,7 +158,7 @@ public class InfoWindow {
mViewWidthOffset = x - mCoordinates.x - offsetX;
close(); //if it was already opened
- mMapView.get().addView(view, lp);
+ mapView.addView(view, lp);
mIsVisible = true;
}
return this;
@@ -196,25 +190,15 @@ public class InfoWindow {
*/
void adaptDefaultMarker(Marker overlayItem, MapView mapView) {
View view = mView.get();
- if (view != null) {
- mMapView = new WeakReference<>(mapView);
- overlayItem.setMapView(mapView);
- String title = overlayItem.getTitle();
- ((TextView) view.findViewById(mTitleId /*R.id.title*/)).setText(title);
- String snippet = overlayItem.getSnippet();
- ((TextView) view.findViewById(mDescriptionId /*R.id.description*/)).setText(snippet);
+ if (view == null) {
+ view = LayoutInflater.from(mapView.getContext()).inflate(mLayoutRes, mapView, false);
+ initialize(view, mapView);
}
-/*
- //handle sub-description, hiding or showing the text view:
- TextView subDescText = (TextView) mView.findViewById(mSubDescriptionId);
- String subDesc = overlayItem.getSubDescription();
- if ("".equals(subDesc)) {
- subDescText.setVisibility(View.GONE);
- } else {
- subDescText.setText(subDesc);
- subDescText.setVisibility(View.VISIBLE);
- }
-*/
+ mMapView = new WeakReference<>(mapView);
+ String title = overlayItem.getTitle();
+ ((TextView) view.findViewById(R.id.infowindow_title)).setText(title);
+ String snippet = overlayItem.getSnippet();
+ ((TextView) view.findViewById(R.id.infowindow_description)).setText(snippet);
}
private void onClose() {
@@ -233,22 +217,6 @@ public class InfoWindow {
return mBoundMarker.get();
}
- /**
- * Given a context, set the resource ids for the layout
- * of the InfoWindow.
- *
- * @param context the apps Context
- */
- private static void setResIds(Context context) {
- String packageName = context.getPackageName(); //get application package name
- mTitleId = context.getResources().getIdentifier("id/infowindow_title", null, packageName);
- mDescriptionId =
- context.getResources().getIdentifier("id/infowindow_description", null, packageName);
- mSubDescriptionId = context.getResources()
- .getIdentifier("id/infowindow_subdescription", null, packageName);
- mImageId = context.getResources().getIdentifier("id/infowindow_image", null, packageName);
- }
-
public void update() {
MapView mapView = mMapView.get();
Marker marker = mBoundMarker.get();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
index 9482afaa2..8b4b66a2a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
@@ -93,17 +93,17 @@ public final class Marker extends Annotation {
View content = infoWindowAdapter.getInfoWindow(this);
if (content != null) {
infoWindow = new InfoWindow(content, getMapView());
- showInfoWindow(infoWindow);
+ showInfoWindow(infoWindow, mapView);
return infoWindow;
}
}
getInfoWindow().adaptDefaultMarker(this, mapView);
- return showInfoWindow(getInfoWindow());
+ return showInfoWindow(getInfoWindow(), mapView);
}
- private InfoWindow showInfoWindow(InfoWindow iw) {
- iw.open(this, getPosition(), 0, topOffsetPixels);
+ private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
+ iw.open(mapView, this, getPosition(), 0, topOffsetPixels);
infoWindowShown = true;
return iw;
}
From 89b051f3865cb48fbe38a450336a6ca4517f6a07 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Mon, 18 Jan 2016 10:18:35 +0100
Subject: [PATCH 09/19] [android] #3593 - added double map view example
---
.../src/main/AndroidManifest.xml | 3 +
.../mapboxsdk/testapp/DoubleMapActivity.java | 147 ++++++++++++++++++
.../mapboxsdk/testapp/MainActivity.java | 17 +-
.../src/main/res/drawable/ic_dns_24dp.xml | 9 ++
.../main/res/layout/fragment_double_map.xml | 27 ++++
.../src/main/res/menu/menu_drawer.xml | 15 +-
.../src/main/res/values/strings.xml | 2 +
7 files changed, 214 insertions(+), 6 deletions(-)
create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java
create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_dns_24dp.xml
create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index af74d52c2..3d5862b51 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -66,6 +66,9 @@
+
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
new file mode 100644
index 000000000..0695fafd1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
index ad9deba18..54be85162 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
@@ -78,10 +78,11 @@
android:icon="@drawable/ic_tilt"
android:title="@string/action_tilt" />
-
+
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index c096284fd..6b30fa7ac 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -20,6 +20,7 @@
Animate Coordinate Change
Custom Layer
Directions Activity
+ Double Map Activity
Main Activity Controls
Main Activity Styles
@@ -43,6 +44,7 @@
Set Visible Bounds
Center map around 2 markers
Remove polylines
+ Double MapView
Move
Ease
From 0ebf5fcaaee7ec90c81ed79b1ecd9843242c35c0 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Mon, 18 Jan 2016 12:17:59 +0100
Subject: [PATCH 10/19] [android] #3507 - fix location listener leak in
UserLocationView
---
.../mapboxsdk/views/UserLocationView.java | 47 ++++++++++++++-----
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
index 67dc9a349..d0f278a52 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
@@ -34,11 +34,13 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
+import java.lang.ref.WeakReference;
+
/**
* This view shows the user's location, as determined from GPS, on the map
* as a dot annotation.
*/
-final class UserLocationView extends View implements LocationListener {
+final class UserLocationView extends View {
private MapView mMapView;
@@ -85,6 +87,7 @@ final class UserLocationView extends View implements LocationListener {
private boolean mPaused = false;
private Location mUserLocation;
+ private UserLocationListener mUserLocationListener;
MapView.OnMyLocationChangeListener mOnMyLocationChangeListener;
@@ -377,14 +380,18 @@ final class UserLocationView extends View implements LocationListener {
setLocation(lastLocation);
}
+ if(mUserLocationListener==null){
+ mUserLocationListener = new UserLocationListener(this);
+ }
+
// Register for Location Updates
- locationServices.addLocationListener(this);
+ locationServices.addLocationListener(mUserLocationListener);
} else {
// Disable location and user dot
setLocation(null);
// Deregister for Location Updates
- locationServices.removeLocationListener(this);
+ locationServices.removeLocationListener(mUserLocationListener);
}
locationServices.toggleGPS(enableGps);
@@ -498,17 +505,27 @@ final class UserLocationView extends View implements LocationListener {
}
}
- /**
- * Callback method for receiving location updates from LocationServices.
- *
- * @param location The new Location data
- */
- @Override
- public void onLocationChanged(Location location) {
- if (mPaused) {
- return;
+ private static class UserLocationListener implements LocationListener{
+
+ private WeakReference mUserLocationView;
+
+ public UserLocationListener(UserLocationView userLocationView) {
+ mUserLocationView = new WeakReference<>(userLocationView);
+ }
+
+
+ /**
+ * Callback method for receiving location updates from LocationServices.
+ *
+ * @param location The new Location data
+ */
+ @Override
+ public void onLocationChanged(Location location) {
+ UserLocationView locationView = mUserLocationView.get();
+ if(locationView!=null && !locationView.isPaused()){
+ locationView.setLocation(location);
+ }
}
- setLocation(location);
}
private boolean isStale(Location location) {
@@ -751,4 +768,8 @@ final class UserLocationView extends View implements LocationListener {
}
}
+ public boolean isPaused(){
+ return mPaused;
+ }
+
}
From 78bedff8f9238c69e29c8c1ccbc6b1136b7786b3 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Mon, 18 Jan 2016 12:41:20 +0100
Subject: [PATCH 11/19] [android] #3556 - Added test to trigger NaN value on
same point, updated LatLng model to handle calls for distance calls of same
point
---
.../com/mapbox/mapboxsdk/geometry/LatLng.java | 5 +++-
.../src/test/java/LatLngTest.java | 27 ++++++++++++-------
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index c340b09e0..f1d05542d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -129,7 +129,6 @@ public class LatLng implements ILatLng, Parcelable, Serializable {
LatLng latLng = (LatLng) o;
return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0 && Double.compare(latLng.longitude, longitude) == 0;
-
}
@Override
@@ -168,6 +167,10 @@ public class LatLng implements ILatLng, Parcelable, Serializable {
* @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 = MathConstants.DEG2RAD * this.latitude;
final double a2 = MathConstants.DEG2RAD * this.longitude;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/LatLngTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/LatLngTest.java
index dd075f327..5b24f32b6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/LatLngTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/LatLngTest.java
@@ -6,6 +6,7 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -43,6 +44,23 @@ public class LatLngTest {
assertEquals("altitude default value", latLng2.getAltitude(), altitude, DELTA);
}
+ @Test
+ public void testDistanceTo() {
+ LatLng latLng1 = new LatLng(0.0, 0.0);
+ LatLng latLng2 = new LatLng(1.0, 1.0);
+ assertEquals("distances should match",
+ latLng1.distanceTo(latLng2),
+ 157425.53710839353, DELTA);
+ }
+
+ @Test
+ public void testDistanceToSamePoint() {
+ LatLng latLng1 = new LatLng(40.71199035644531, -74.0081);
+ LatLng latLng2 = new LatLng(40.71199035644531, -74.0081);
+ double distance = latLng1.distanceTo(latLng2);
+ assertEquals("distance should match", 0.0, distance, DELTA);
+ }
+
/*
* A sample test where Mockito is necessary
*/
@@ -86,13 +104,4 @@ public class LatLngTest {
"LatLng [longitude=3.4, latitude=1.2, altitude=5.6]");
}
- @Test
- public void testDistanceTo() {
- LatLng latLng1 = new LatLng(0.0, 0.0);
- LatLng latLng2 = new LatLng(1.0, 1.0);
- assertEquals("distances should match",
- latLng1.distanceTo(latLng2),
- 157425.53710839353, DELTA);
- }
-
}
From fabc457adf04977bd73fd115b9e19383a89402f3 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Mon, 18 Jan 2016 13:26:23 +0100
Subject: [PATCH 12/19] [android] #3338 - add javadoc annotations package
---
.../java/com/mapbox/mapboxsdk/MapFragment.java | 14 ++++++++++++++
.../mapbox/mapboxsdk/annotations/Annotation.java | 8 +++++---
.../com/mapbox/mapboxsdk/annotations/Icon.java | 4 ++++
.../mapboxsdk/annotations/IconFactory.java | 4 ++++
.../mapbox/mapboxsdk/annotations/InfoWindow.java | 9 ++++++---
.../com/mapbox/mapboxsdk/annotations/Marker.java | 16 +++++++++++++---
.../mapboxsdk/annotations/MarkerOptions.java | 6 +++---
.../mapbox/mapboxsdk/annotations/MultiPoint.java | 3 +++
.../mapboxsdk/annotations/PolygonOptions.java | 5 +++++
.../mapboxsdk/annotations/PolylineOptions.java | 5 +++++
.../mapboxsdk/geometry/CoordinateBounds.java | 2 +-
.../mapboxsdk/geometry/CoordinateRegion.java | 2 +-
.../mapboxsdk/geometry/CoordinateSpan.java | 2 +-
.../com/mapbox/mapboxsdk/geometry/ILatLng.java | 2 +-
.../mapboxsdk/geometry/IProjectedMeters.java | 3 +++
.../com/mapbox/mapboxsdk/geometry/LatLng.java | 5 +++--
.../mapbox/mapboxsdk/geometry/LatLngZoom.java | 3 +++
.../mapboxsdk/geometry/ProjectedMeters.java | 6 ++++--
18 files changed, 79 insertions(+), 20 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
index 98d0f7965..572598996 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
@@ -10,6 +10,20 @@ import android.view.ViewGroup;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.views.MapView;
+/**
+ * Fragment wrapper around a {@link MapView}.
+ *
+ * A Map component in an app. This fragment is the simplest way to place a map in an application.
+ * It's a wrapper around a view of a map to automatically handle the necessary life cycle needs.
+ * Being a fragment, this component can be added to an activity's layout or can dynamically be added
+ * using a FragmentManager.
+ *
+ *
+ * To get a reference to the MapView, use {@link #getMap()}
+ *
+ *
+ * @see #getMap()
+ */
public class MapFragment extends Fragment {
//
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
index bf8999878..813e489e9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
@@ -5,10 +5,12 @@ import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.views.MapView;
/**
- * Annotation is the most general kind of overlay on top of a map,
- * from which {@link InfoWindow} and {@link Marker} are derived: it manages
- * attachment to a map and identification, but does not require
+ * Annotation is a overlay on top of a {@link MapView},
+ * from which {@link Polygon}, {@link Polyline} and {@link Marker} are derived.
+ *
+ * it manages attachment to a map and identification, but does not require
* content to be placed at a geographical point.
+ *
*/
public abstract class Annotation implements Comparable {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
index d7e28dde7..b9691914e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
@@ -2,6 +2,10 @@ package com.mapbox.mapboxsdk.annotations;
import android.graphics.Bitmap;
+/**
+ * Icon is the visual representation of a {@link Marker} on a {@link com.mapbox.mapboxsdk.views.MapView}.
+ * @see Marker
+ */
public final class Icon {
private Bitmap mBitmap;
private String mId;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
index 8d58866ac..bee4ec47c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
@@ -22,6 +22,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+/**
+ * Factory for creating {@link Icon} objects.
+ * @see Icon
+ */
public final class IconFactory {
private static final String ICON_ID_PREFIX = "com.mapbox.icons.icon_";
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
index 2ace201c9..696301cf5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
@@ -17,19 +17,22 @@ import java.lang.ref.WeakReference;
/**
*
- * A tooltip view. This is a UI element placed over a map at a specific geographic
- * location.
+ * InfoWindow is a tooltip shown when a {@link Marker} is tapped.
+ *
+ *
+ * This is a UI element placed over a map at a specific geographic location.
*
*/
public class InfoWindow {
private WeakReference mBoundMarker;
private WeakReference mMapView;
+ protected WeakReference mView;
+
private float mMarkerHeightOffset;
private float mViewWidthOffset;
private PointF mCoordinates;
private boolean mIsVisible;
- protected WeakReference mView;
@LayoutRes
private int mLayoutRes;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
index 8b4b66a2a..346380144 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
@@ -9,9 +9,10 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.views.MapView;
/**
- * A marker is a map overlay that shows an icon image at a specific
- * geographical location and can be associated with a {@link InfoWindow}
- * that is shown when the marker is tapped.
+ * Marker is an annotation that shows an icon image at a geographical location.
+ *
+ * An {@link InfoWindow} can be shown when a Marker is pressed
+ *
*/
public final class Marker extends Annotation {
@@ -54,6 +55,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @return boolean State of a InfoWindow
*/
public boolean isInfoWindowShown() {
return infoWindowShown;
@@ -69,6 +72,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @param icon The icon to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
@@ -84,6 +89,9 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @param mapView The MapView to show the InfoWindow on.
+ * @return infoWindow The infoWindow to show
*/
public InfoWindow showInfoWindow(@NonNull MapView mapView) {
setMapView(mapView);
@@ -127,6 +135,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @param topOffsetPixels the pixels to have as offset
*/
public void setTopOffsetPixels(int topOffsetPixels) {
this.topOffsetPixels = topOffsetPixels;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
index 69e8b03bd..a83a6991b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
@@ -10,9 +10,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
/**
*
- * A builder object for the options configuration {@link com.mapbox.mapboxsdk.annotations.Marker} and
- * {@link com.mapbox.mapboxsdk.annotations.InfoWindow}
- * instances on maps.
+ * Builder for composing {@link com.mapbox.mapboxsdk.annotations.Marker} objects.
*
*
* Example
@@ -70,6 +68,8 @@ public final class MarkerOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @return Marker The build marker
*/
public Marker getMarker() {
return marker;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
index 5c1dfb119..d2aaea1d1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
@@ -5,6 +5,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
+/**
+ * Multipoint is an abstract annotation for combining geographical locations.
+ */
public abstract class MultiPoint extends Annotation {
private List points;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
index c716d10ed..30847807b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
@@ -9,6 +9,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
+/**
+ * Builder for composing {@link Polygon} objects.
+ */
public final class PolygonOptions implements Parcelable {
public static final Parcelable.Creator CREATOR
@@ -96,6 +99,8 @@ public final class PolygonOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
+ *
+ * @return Polygon the Polygon to return
*/
public Polygon getPolygon() {
return polygon;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
index d48858c7d..1e625c10f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
@@ -8,6 +8,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
+/**
+ * Builder for composing {@link Polyline} objects.
+ */
public final class PolylineOptions implements Parcelable {
@@ -83,6 +86,7 @@ public final class PolylineOptions implements Parcelable {
* Sets the color of the polyline.
*
* @param color - the color in ARGB format
+ * @return PolyLineOptions The builder used to build a Polyline
*/
public PolylineOptions color(int color) {
polyline.setColor(color);
@@ -95,6 +99,7 @@ public final class PolylineOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
+ * @return PolyLine The polyline build by this class.
*/
public Polyline getPolyline() {
return polyline;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
index 1ad584f8c..4d3e94f78 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.geometry;
/**
- * Implementation of iOS MGLCoordinateBounds
+ * A rectangular geograpical region defined by a south west {@link LatLng} and a north east {@link LatLng}.
*/
public class CoordinateBounds {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
index a70bb05a4..65b30746f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.geometry;
/**
- * Implementation of iOS MKCoordinateRegion
+ * A geographical region defined by a {@link LatLng} and a {@link CoordinateSpan}.
*/
public class CoordinateRegion {
private LatLng center;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
index 79361f725..097e88a76 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.geometry;
/**
- * Implementation of iOS MKCoordinateSpan
+ * A geographical span defined by its latitude and longitude span.
*/
public class CoordinateSpan {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
index 892d0ad4a..afd22e5dd 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.geometry;
/**
- * A Latitude, Longitude point.
+ * Describes a latitude, longitude point.
*/
public interface ILatLng {
double getLatitude();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
index 5aa5f607e..43fe25f8e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
@@ -1,5 +1,8 @@
package com.mapbox.mapboxsdk.geometry;
+/**
+ * Describes a projection in Mercator meters.
+ */
public interface IProjectedMeters {
double getNorthing();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index f1d05542d..876a12720 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -10,9 +10,10 @@ import com.mapbox.mapboxsdk.constants.MathConstants;
import java.io.Serializable;
/**
+ * A geographical location which contains a single latitude, longitude pair, with
+ * optional altitude.
*
- * This class is container for a single latitude, longitude pair, with
- * optional altitude. Latitude and longitude are expressed as decimal degrees
+ * Latitude and longitude are expressed as decimal degrees
* in the WGS84 datum. By default, altitude is 0.0, or sea level.
*
*
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
index 9e453a391..349c09898 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
@@ -5,6 +5,9 @@ import android.os.Parcelable;
import java.io.Serializable;
+/**
+ * A geographical location which contains a {@link LatLng}, zoom pair.
+ */
public class LatLngZoom extends LatLng implements Parcelable, Serializable {
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
index fc821e887..61a03ff15 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
@@ -6,10 +6,12 @@ import android.os.Parcelable;
import java.io.Serializable;
/**
- * ProjectedMeters is an internal representation of longitude, latitude points that
- * have been projected into Mapbox GL's Mercator projection. Instead of decimal
+ * ProjectedMeters is a projection of longitude, latitude points in Mercator meters.
+ *
+ * these have been projected into Mapbox GL's Mercator projection. Instead of decimal
* degrees, it uses Mercator meters (which are notably not equivalent to SI meters)
* except at the equator.
+ *
*/
public class ProjectedMeters implements IProjectedMeters, Parcelable, Serializable {
From 5ff95d45240cc340d22c37bb13e4289b4eab40b7 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Tue, 19 Jan 2016 12:03:52 +0100
Subject: [PATCH 13/19] [android] #3525 - fix ConnectivityManager context leak
---
.../src/main/java/com/mapbox/mapboxsdk/views/MapView.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index c475eccf1..fdfc3faaf 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -805,7 +805,7 @@ public final class MapView extends FrameLayout {
mZoomButtonsController.setOnZoomListener(new OnZoomListener());
// Check current connection status
- ConnectivityManager connectivityManager = (ConnectivityManager) context
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
boolean isConnected = (activeNetwork != null) && activeNetwork.isConnectedOrConnecting();
From 6b3745c68dcfe98d746d478539b035ea8699f736 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Tue, 19 Jan 2016 10:25:05 +0100
Subject: [PATCH 14/19] [android] #3156 - improving marker selection touch
handling
---
.../com/mapbox/mapboxsdk/views/MapView.java | 60 ++++++-------------
1 file changed, 17 insertions(+), 43 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index fdfc3faaf..8db7fbf77 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -3186,9 +3186,9 @@ public final class MapView extends FrameLayout {
// Open / Close InfoWindow
PointF tapPoint = new PointF(e.getX(), e.getY());
- final float toleranceSides = 30 * mScreenDensity;
- final float toleranceTop = 40 * mScreenDensity;
- final float toleranceBottom = 10 * mScreenDensity;
+ final float toleranceSides = 15 * mScreenDensity;
+ final float toleranceTop = 20 * mScreenDensity;
+ final float toleranceBottom = 5 * mScreenDensity;
RectF tapRect = new RectF(tapPoint.x - toleranceSides, tapPoint.y + toleranceTop,
tapPoint.x + toleranceSides, tapPoint.y - toleranceBottom);
@@ -3201,52 +3201,27 @@ public final class MapView extends FrameLayout {
);
BoundingBox tapBounds = BoundingBox.fromLatLngs(corners);
-
List nearbyMarkers = getMarkersInBounds(tapBounds);
+ long newSelectedMarkerId = -1;
- long newSelectedMarkerId;
-
- if (nearbyMarkers.size() > 0) {
-
- // there is at least one nearby marker; select one
- //
- // first, sort for comparison and iteration
+ if (nearbyMarkers!=null && nearbyMarkers.size() > 0) {
Collections.sort(nearbyMarkers);
-
- if (nearbyMarkers == mMarkersNearLastTap) {
-
- // TODO: We still need to adapt this logic to the new mSelectedMarkers list,
- // though the basic functionality is there.
-
- // the selection candidates haven't changed; cycle through them
-// if (mSelectedMarker != null
-// && (mSelectedMarker.getId() == mMarkersNearLastTap.get(mMarkersNearLastTap.size() - 1).getId())) {
-// // the selected marker is the last in the set; cycle back to the first
-// // note: this could be the selected marker if only one in set
-// newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
-// } else if (mSelectedMarker != null) {
-// // otherwise increment the selection through the candidates
-// long result = mMarkersNearLastTap.indexOf(mSelectedMarker);
-// newSelectedMarkerId = mMarkersNearLastTap.get((int) result + 1).getId();
-// } else {
- // no current selection; select the first one
- newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
-// }
- } else {
- // start tracking a new set of nearby markers
- mMarkersNearLastTap = nearbyMarkers;
-
- // select the first one
- newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
+ for (Marker nearbyMarker : nearbyMarkers) {
+ boolean found = false;
+ for (Marker selectedMarker : mSelectedMarkers) {
+ if(selectedMarker.equals(nearbyMarker)){
+ found = true;
+ }
+ }
+ if(!found){
+ newSelectedMarkerId = nearbyMarker.getId();
+ break;
+ }
}
-
- } else {
- // there are no nearby markers; deselect if necessary
- newSelectedMarkerId = -1;
+ mMarkersNearLastTap = nearbyMarkers;
}
if (newSelectedMarkerId >= 0) {
-
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
@@ -3259,7 +3234,6 @@ public final class MapView extends FrameLayout {
}
}
}
-
} else {
// deselect any selected marker
deselectMarkers();
From 06e420939f1dc172260adc2a7a8ee1a4e5ba62fc Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Tue, 19 Jan 2016 12:37:52 +0100
Subject: [PATCH 15/19] [android] #3604 - polyline activity memory leak fix
---
.../mapboxsdk/testapp/PolylineActivity.java | 75 +++++++++----------
1 file changed, 35 insertions(+), 40 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
index e000cf079..d2d266a31 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
@@ -22,6 +22,12 @@ import java.util.List;
public class PolylineActivity extends AppCompatActivity {
private static final String STATE_POLYLINE_OPTIONS = "polylineOptions";
+ private static final LatLng ANDORRA = new LatLng(42.505777, 1.52529);
+ private static final LatLng LUXEMBOURG = new LatLng(49.815273, 6.129583);
+ private static final LatLng MONACO = new LatLng(43.738418, 7.424616);
+ private static final LatLng VATICAN_CITY = new LatLng(41.902916, 12.453389);
+ private static final LatLng SAN_MARINO = new LatLng(43.942360, 12.457777);
+ private static final LatLng LIECHTENSTEIN = new LatLng(47.166000, 9.555373);
private List mPolylines;
private ArrayList mPolylineOptions = new ArrayList<>();
@@ -48,8 +54,9 @@ public class PolylineActivity extends AppCompatActivity {
if (savedInstanceState != null) {
mPolylineOptions = savedInstanceState.getParcelableArrayList(STATE_POLYLINE_OPTIONS);
} else {
- mPolylineOptions.addAll(PolylineProvider.getAll());
+ mPolylineOptions.addAll(getAllPolylines());
}
+
mPolylines = mMapView.addPolylines(mPolylineOptions);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@@ -65,12 +72,38 @@ public class PolylineActivity extends AppCompatActivity {
}
}
mPolylineOptions.clear();
- mPolylineOptions.addAll(PolylineProvider.getRandomLine());
+ mPolylineOptions.addAll(getRandomLine());
mPolylines = mMapView.addPolylines(mPolylineOptions);
}
});
}
+ private List getAllPolylines() {
+ List options = new ArrayList<>();
+ options.add(generatePolyline(ANDORRA, LUXEMBOURG, "#F44336"));
+ options.add(generatePolyline(ANDORRA, MONACO, "#FF5722"));
+ options.add(generatePolyline(MONACO, VATICAN_CITY, "#673AB7"));
+ options.add(generatePolyline(VATICAN_CITY, SAN_MARINO, "#009688"));
+ options.add(generatePolyline(SAN_MARINO, LIECHTENSTEIN, "#795548"));
+ options.add(generatePolyline(LIECHTENSTEIN, LUXEMBOURG, "#3F51B5"));
+ return options;
+ }
+
+ private PolylineOptions generatePolyline(LatLng start, LatLng end, String color) {
+ PolylineOptions line = new PolylineOptions();
+ line.add(start);
+ line.add(end);
+ line.color(Color.parseColor(color));
+ return line;
+ }
+
+ public List getRandomLine() {
+ final List randomLines = getAllPolylines();
+ Collections.shuffle(randomLines);
+ return new ArrayList(){{
+ add(randomLines.get(0));
+ }};
+ }
@Override
protected void onStart() {
@@ -139,42 +172,4 @@ public class PolylineActivity extends AppCompatActivity {
}
}
- private static class PolylineProvider {
- private static final LatLng ANDORRA = new LatLng(42.505777, 1.52529);
- private static final LatLng LUXEMBOURG = new LatLng(49.815273, 6.129583);
- private static final LatLng MONACO = new LatLng(43.738418, 7.424616);
- private static final LatLng VATICAN_CITY = new LatLng(41.902916, 12.453389);
- private static final LatLng SAN_MARINO = new LatLng(43.942360, 12.457777);
- private static final LatLng LIECHTENSTEIN = new LatLng(47.166000, 9.555373);
-
- private static final List POLYLINES = new ArrayList() {{
- add(generatePolyline(ANDORRA, LUXEMBOURG, "#F44336"));
- add(generatePolyline(ANDORRA, MONACO, "#FF5722"));
- add(generatePolyline(MONACO, VATICAN_CITY, "#673AB7"));
- add(generatePolyline(VATICAN_CITY, SAN_MARINO, "#009688"));
- add(generatePolyline(SAN_MARINO, LIECHTENSTEIN, "#795548"));
- add(generatePolyline(LIECHTENSTEIN, LUXEMBOURG, "#3F51B5"));
- }};
-
- private static PolylineOptions generatePolyline(LatLng start, LatLng end, String color) {
- PolylineOptions line = new PolylineOptions();
- line.add(start);
- line.add(end);
- line.color(Color.parseColor(color));
- return line;
- }
-
- public static List getAll() {
- return POLYLINES;
- }
-
- public static List getRandomLine() {
- List randomLines = new ArrayList<>();
- Collections.shuffle(POLYLINES);
- randomLines.add(POLYLINES.get(0));
- return randomLines;
- }
-
- }
-
}
From 8ffe776141bc5740438f65ef6b66ff9663c6204e Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Tue, 19 Jan 2016 13:24:46 +0100
Subject: [PATCH 16/19] [android] #3503 - remove serialisable interface from
classes in geometry package, implemented parcable on CoordinateBounds,
CoordinateRegion and CoordinateSpan. Enforced Android code conventions on
those classes.
---
.../mapboxsdk/geometry/BoundingBox.java | 2 +-
.../mapboxsdk/geometry/CoordinateBounds.java | 65 ++++++++++++++-----
.../mapboxsdk/geometry/CoordinateRegion.java | 58 +++++++++++++----
.../mapboxsdk/geometry/CoordinateSpan.java | 62 +++++++++++++-----
.../com/mapbox/mapboxsdk/geometry/LatLng.java | 2 +-
.../mapbox/mapboxsdk/geometry/LatLngZoom.java | 2 +-
.../mapboxsdk/geometry/ProjectedMeters.java | 2 +-
.../src/test/java/CoordinateBoundsTest.java | 2 +-
8 files changed, 148 insertions(+), 47 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java
index ca805b38e..72a851e1a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java
@@ -9,7 +9,7 @@ import java.util.List;
/**
* A rectangular geographical area defined in latitude and longitude units.
*/
-public final class BoundingBox implements Parcelable, Serializable {
+public final class BoundingBox implements Parcelable {
private final double mLatNorth;
private final double mLatSouth;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
index 4d3e94f78..fefc2502d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
@@ -1,41 +1,52 @@
package com.mapbox.mapboxsdk.geometry;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+
/**
* A rectangular geograpical region defined by a south west {@link LatLng} and a north east {@link LatLng}.
*/
-public class CoordinateBounds {
+public class CoordinateBounds implements Parcelable {
- private LatLng southWest;
- private LatLng northEast;
+ private LatLng mSouthWest;
+ private LatLng mNorthEast;
- public CoordinateBounds(LatLng southWest, LatLng northEast) {
- this.southWest = southWest;
- this.northEast = northEast;
+ public CoordinateBounds(@NonNull Parcel in) {
+ mSouthWest = in.readParcelable(LatLng.class.getClassLoader());
+ mNorthEast = in.readParcelable(LatLng.class.getClassLoader());
}
+ public CoordinateBounds(@NonNull LatLng southWest, @NonNull LatLng northEast) {
+ mSouthWest = southWest;
+ mNorthEast = northEast;
+ }
+
+ @NonNull
public LatLng getSouthWest() {
- return southWest;
+ return mSouthWest;
}
- public void setSouthWest(LatLng southWest) {
- this.southWest = southWest;
+ public void setSouthWest(@NonNull LatLng mSouthWest) {
+ this.mSouthWest = mSouthWest;
}
+ @NonNull
public LatLng getNorthEast() {
- return northEast;
+ return mNorthEast;
}
- public void setNorthEast(LatLng northEast) {
- this.northEast = northEast;
+ public void setNorthEast(@NonNull LatLng mNorthEast) {
+ this.mNorthEast = mNorthEast;
}
@Override
public int hashCode() {
int result;
long temp;
- temp = southWest.hashCode();
+ temp = mSouthWest.hashCode();
result = (int) (temp ^ (temp >>> 32));
- temp = northEast.hashCode();
+ temp = mNorthEast.hashCode();
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@@ -53,6 +64,30 @@ public class CoordinateBounds {
@Override
public String toString() {
- return "CoordinateBounds [northEast[" + getNorthEast() + "], southWest[]" + getSouthWest() + "]";
+ return "CoordinateBounds [mNorthEast[" + getNorthEast() + "], mSouthWest[]" + getSouthWest() + "]";
+ }
+
+ public static final Parcelable.Creator CREATOR =
+ new Parcelable.Creator() {
+ @Override
+ public CoordinateBounds createFromParcel(Parcel in) {
+ return new CoordinateBounds(in);
+ }
+
+ @Override
+ public CoordinateBounds[] newArray(int size) {
+ return new CoordinateBounds[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int arg1) {
+ out.writeParcelable(mSouthWest, arg1);
+ out.writeParcelable(mNorthEast, arg1);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
index 65b30746f..c7c0aa1c4 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
@@ -1,30 +1,64 @@
package com.mapbox.mapboxsdk.geometry;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+
/**
* A geographical region defined by a {@link LatLng} and a {@link CoordinateSpan}.
*/
-public class CoordinateRegion {
- private LatLng center;
- private CoordinateSpan span;
+public class CoordinateRegion implements Parcelable{
- public CoordinateRegion(final LatLng center, final CoordinateSpan span) {
- this.center = center;
- this.span = span;
+ private LatLng mCenter;
+ private CoordinateSpan mSpan;
+
+ public CoordinateRegion(@NonNull Parcel in){
+ mCenter = in.readParcelable(LatLng.class.getClassLoader());
+ mSpan = in.readParcelable(CoordinateSpan.class.getClassLoader());
+ }
+
+ public CoordinateRegion(@NonNull LatLng center, @NonNull CoordinateSpan span) {
+ mCenter = center;
+ mSpan = span;
}
public LatLng getCenter() {
- return center;
+ return mCenter;
}
- public void setCenter(final LatLng center) {
- this.center = center;
+ public void setCenter(@NonNull LatLng center) {
+ mCenter = center;
}
public CoordinateSpan getSpan() {
- return span;
+ return mSpan;
}
- public void setSpan(final CoordinateSpan span) {
- this.span = span;
+ public void setSpan(@NonNull CoordinateSpan span) {
+ this.mSpan = span;
+ }
+
+ public static final Parcelable.Creator CREATOR =
+ new Parcelable.Creator() {
+ @Override
+ public CoordinateRegion createFromParcel(Parcel in) {
+ return new CoordinateRegion(in);
+ }
+
+ @Override
+ public CoordinateRegion[] newArray(int size) {
+ return new CoordinateRegion[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int arg1) {
+ out.writeParcelable(mCenter, arg1);
+ out.writeParcelable(mSpan, arg1);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
index 097e88a76..a43757713 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
@@ -1,32 +1,41 @@
package com.mapbox.mapboxsdk.geometry;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+
/**
* A geographical span defined by its latitude and longitude span.
*/
-public class CoordinateSpan {
+public class CoordinateSpan implements Parcelable {
- private double latitudeSpan;
- private double longitudeSpan;
+ private double mLatitudeSpan;
+ private double mLongitudeSpan;
- public CoordinateSpan(final double latitudeSpan, final double longitudeSpan) {
- this.latitudeSpan = latitudeSpan;
- this.longitudeSpan = longitudeSpan;
+ public CoordinateSpan(@NonNull Parcel in){
+ mLatitudeSpan = in.readDouble();
+ mLongitudeSpan = in.readDouble();
+ }
+
+ public CoordinateSpan(double latitudeSpan, double longitudeSpan) {
+ mLatitudeSpan = latitudeSpan;
+ mLongitudeSpan = longitudeSpan;
}
public double getLatitudeSpan() {
- return latitudeSpan;
+ return mLatitudeSpan;
}
- public void setLatitudeSpan(final double latitudeSpan) {
- this.latitudeSpan = latitudeSpan;
+ public void setLatitudeSpan(double latitudeSpan) {
+ mLatitudeSpan = latitudeSpan;
}
public double getLongitudeSpan() {
- return longitudeSpan;
+ return mLongitudeSpan;
}
- public void setLongitudeSpan(final double longitudeSpan) {
- this.longitudeSpan = longitudeSpan;
+ public void setLongitudeSpan(double longitudeSpan) {
+ mLongitudeSpan = longitudeSpan;
}
@Override
@@ -34,10 +43,33 @@ public class CoordinateSpan {
if (this == o) return true;
if (o instanceof CoordinateSpan) {
CoordinateSpan other = (CoordinateSpan) o;
- return longitudeSpan == other.getLongitudeSpan()
- && latitudeSpan == other.getLatitudeSpan();
+ return mLongitudeSpan == other.getLongitudeSpan()
+ && mLatitudeSpan == other.getLatitudeSpan();
}
return false;
}
-}
+ public static final Parcelable.Creator CREATOR =
+ new Parcelable.Creator() {
+ @Override
+ public CoordinateSpan createFromParcel(Parcel in) {
+ return new CoordinateSpan(in);
+ }
+
+ @Override
+ public CoordinateSpan[] newArray(int size) {
+ return new CoordinateSpan[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int arg1) {
+ out.writeDouble(mLatitudeSpan);
+ out.writeDouble(mLongitudeSpan);
+ }
+}
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index 876a12720..f24c2ed43 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -21,7 +21,7 @@ import java.io.Serializable;
* data automatically, so all data enters in the WGS84 datum.
*
*/
-public class LatLng implements ILatLng, Parcelable, Serializable {
+public class LatLng implements ILatLng, Parcelable {
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public LatLng createFromParcel(Parcel in) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
index 349c09898..6e24faaa9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
@@ -8,7 +8,7 @@ import java.io.Serializable;
/**
* A geographical location which contains a {@link LatLng}, zoom pair.
*/
-public class LatLngZoom extends LatLng implements Parcelable, Serializable {
+public class LatLngZoom extends LatLng implements Parcelable {
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public LatLngZoom createFromParcel(Parcel in) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
index 61a03ff15..06a58fe8a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
@@ -13,7 +13,7 @@ import java.io.Serializable;
* except at the equator.
*
*/
-public class ProjectedMeters implements IProjectedMeters, Parcelable, Serializable {
+public class ProjectedMeters implements IProjectedMeters, Parcelable {
public static final Creator CREATOR = new Creator() {
public ProjectedMeters createFromParcel(Parcel in) {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/CoordinateBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/CoordinateBoundsTest.java
index a5d389130..1dc4be723 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/CoordinateBoundsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/CoordinateBoundsTest.java
@@ -44,7 +44,7 @@ public class CoordinateBoundsTest {
CoordinateBounds coordinateBounds = new CoordinateBounds(northEast, southWest);
assertEquals("string should match",
coordinateBounds.toString(),
- "CoordinateBounds [northEast[" + coordinateBounds.getNorthEast() + "], southWest[]" + coordinateBounds.getSouthWest() + "]");
+ "CoordinateBounds [mNorthEast[" + coordinateBounds.getNorthEast() + "], mSouthWest[]" + coordinateBounds.getSouthWest() + "]");
}
@Test
From fa84283a9d2b1b38332012abc989f992d29d31f0 Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Tue, 19 Jan 2016 14:56:52 +0100
Subject: [PATCH 17/19] [android] #3608 - upgrade okhttp3 to version 2
---
platform/android/MapboxGLAndroidSDK/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 55beb8dea..c194a8c34 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -25,7 +25,7 @@ dependencies {
compile "com.android.support:support-annotations:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
- compile 'com.squareup.okhttp3:okhttp:3.0.0'
+ compile 'com.squareup.okhttp3:okhttp:3.0.1'
compile 'com.mapzen.android:lost:1.0.1'
}
From 9672f2ba505587927f92112ca892258b28a721a3 Mon Sep 17 00:00:00 2001
From: Antonio Zugaldia
Date: Wed, 13 Jan 2016 17:22:14 -0500
Subject: [PATCH 18/19] sample geocoder activity
---
.../MapboxGLAndroidSDKTestApp/build.gradle | 5 +
.../src/main/AndroidManifest.xml | 3 +
.../mapboxsdk/testapp/GeocoderActivity.java | 158 ++++++++++++++++++
.../mapboxsdk/testapp/MainActivity.java | 6 +-
.../src/main/res/layout/activity_geocoder.xml | 27 +++
.../src/main/res/menu/menu_drawer.xml | 15 +-
.../src/main/res/values/strings.xml | 1 +
7 files changed, 208 insertions(+), 7 deletions(-)
create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index 815fe8d00..41d75cc0b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -86,6 +86,11 @@ dependencies {
transitive=true
}
+ // Geocoder SDK
+ compile ('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0@aar'){
+ transitive=true
+ }
+
// Testing dependencies
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 3d5862b51..d5a6df956 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -66,6 +66,9 @@
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
new file mode 100644
index 000000000..200ca8ac0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
@@ -0,0 +1,158 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.widget.TextView;
+
+import com.mapbox.geocoder.GeocoderCriteria;
+import com.mapbox.geocoder.MapboxGeocoder;
+import com.mapbox.geocoder.service.models.GeocoderFeature;
+import com.mapbox.geocoder.service.models.GeocoderResponse;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.utils.ApiAccess;
+import com.mapbox.mapboxsdk.views.MapView;
+
+import java.util.List;
+
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+public class GeocoderActivity extends AppCompatActivity {
+
+ private static final String LOG_TAG = "GeocoderActivity";
+
+ private MapView mapView;
+ private TextView textView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_geocoder);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ textView = (TextView) findViewById(R.id.message);
+ setMessage("Tap the map to trigger the geocoder.");
+
+ LatLng dupontCircle = new LatLng(38.90962, -77.04341);
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setAccessToken(ApiAccess.getToken(this));
+ mapView.setStyleUrl(Style.MAPBOX_STREETS);
+ mapView.setCenterCoordinate(dupontCircle);
+ mapView.setZoomLevel(15);
+ mapView.onCreate(savedInstanceState);
+
+ mapView.setOnMapClickListener(new MapView.OnMapClickListener() {
+ @Override
+ public void onMapClick(LatLng point) {
+ setMessage("Geocoding...");
+ mapView.removeAllAnnotations();
+ mapView.addMarker(new MarkerOptions()
+ .position(point)
+ .title("Your finger is here"));
+ geocode(point);
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ /*
+ * Forward geocoding
+ */
+
+ private void geocode(LatLng point) {
+ MapboxGeocoder client = new MapboxGeocoder.Builder()
+ .setAccessToken(ApiAccess.getToken(this))
+ .setCoordinates(point.getLongitude(), point.getLatitude())
+ .setType(GeocoderCriteria.TYPE_POI)
+ .build();
+
+ client.enqueue(new Callback() {
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+ List results = response.body().getFeatures();
+ if (results.size() > 0) {
+ String placeName = results.get(0).getPlaceName();
+ setSuccess(placeName);
+ } else {
+ setMessage("No results.");
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ setError(t.getMessage());
+ }
+ });
+
+ }
+
+ /*
+ * Update text view
+ */
+
+ private void setMessage(String message) {
+ Log.d(LOG_TAG, "Message: " + message);
+ textView.setText(message);
+ }
+
+ private void setSuccess(String placeName) {
+ Log.d(LOG_TAG, "Place name: " + placeName);
+ textView.setText(placeName);
+ }
+
+ private void setError(String message) {
+ Log.e(LOG_TAG, "Error: " + message);
+ textView.setText("Error: " + message);
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
index a6920567f..645104644 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
@@ -182,8 +182,6 @@ public class MainActivity extends AppCompatActivity {
mFpsTextView = (TextView) findViewById(R.id.view_fps);
mFpsTextView.setText("");
- mMapView.setRotateEnabled(false);
-
mLocationFAB = (FloatingActionButton) findViewById(R.id.locationFAB);
mLocationFAB.setOnClickListener(new View.OnClickListener() {
@Override
@@ -422,6 +420,10 @@ public class MainActivity extends AppCompatActivity {
}
return true;
+ case R.id.action_geocoder:
+ startActivity(new Intent(getApplicationContext(), GeocoderActivity.class));
+ return true;
+
default:
return changeMapStyle(menuItem.getItemId());
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
new file mode 100644
index 000000000..ce0802385
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
index 54be85162..2fd9e6c75 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
@@ -78,11 +78,10 @@
android:icon="@drawable/ic_tilt"
android:title="@string/action_tilt" />
-
+
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 6b30fa7ac..6caf0f7df 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -20,6 +20,7 @@
Animate Coordinate Change
Custom Layer
Directions Activity
+ Geocoder Activity
Double Map Activity
Main Activity Controls
From 3797bbf75c783900b6fa9af1942953c624c2e588 Mon Sep 17 00:00:00 2001
From: Brad Leege
Date: Wed, 20 Jan 2016 11:26:34 -0500
Subject: [PATCH 19/19] [android] #3537 - Updating version to 3.1.0 for release
and fabric
---
platform/android/MapboxGLAndroidSDK/gradle.properties | 2 +-
.../fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties
index 8b50b5b17..bd2d4f385 100644
--- a/platform/android/MapboxGLAndroidSDK/gradle.properties
+++ b/platform/android/MapboxGLAndroidSDK/gradle.properties
@@ -1,5 +1,5 @@
GROUP=com.mapbox.mapboxsdk
-VERSION_NAME=3.1.0-SNAPSHOT
+VERSION_NAME=3.1.0
POM_DESCRIPTION=Mapbox GL Android SDK
POM_URL=https://github.com/mapbox/mapbox-gl-native
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
index 030ebae5c..e09bb0110 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
+++ b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
@@ -1,3 +1,3 @@
fabric-identifier=com.mapbox.mapboxsdk.mapbox-android-sdk
-fabric-version=3.0.0
+fabric-version=3.1.0
fabric-build-type=binary