react-native-maps 1.21.0-alpha.57 → 1.21.0-alpha.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -68,6 +68,8 @@ import com.google.maps.android.data.kml.KmlContainer;
|
|
|
68
68
|
import com.google.maps.android.data.kml.KmlLayer;
|
|
69
69
|
import com.google.maps.android.data.kml.KmlPlacemark;
|
|
70
70
|
|
|
71
|
+
import org.json.JSONException;
|
|
72
|
+
import org.json.JSONObject;
|
|
71
73
|
import org.xmlpull.v1.XmlPullParserException;
|
|
72
74
|
|
|
73
75
|
import java.io.IOException;
|
|
@@ -78,1506 +80,1566 @@ import java.util.HashMap;
|
|
|
78
80
|
import java.util.List;
|
|
79
81
|
import java.util.Map;
|
|
80
82
|
import java.util.concurrent.ExecutionException;
|
|
83
|
+
|
|
81
84
|
import com.rnmaps.fabric.event.*;
|
|
82
85
|
|
|
83
86
|
public class MapView extends com.google.android.gms.maps.MapView implements GoogleMap.InfoWindowAdapter,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
87
|
+
GoogleMap.OnMarkerDragListener, OnMapReadyCallback, GoogleMap.OnPoiClickListener, GoogleMap.OnIndoorStateChangeListener {
|
|
88
|
+
public GoogleMap map;
|
|
89
|
+
private MarkerManager markerManager;
|
|
90
|
+
private MarkerManager.Collection markerCollection;
|
|
91
|
+
private PolylineManager polylineManager;
|
|
92
|
+
private PolylineManager.Collection polylineCollection;
|
|
93
|
+
private PolygonManager polygonManager;
|
|
94
|
+
private PolygonManager.Collection polygonCollection;
|
|
95
|
+
private CircleManager.Collection circleCollection;
|
|
96
|
+
private GroundOverlayManager groundOverlayManager;
|
|
97
|
+
private GroundOverlayManager.Collection groundOverlayCollection;
|
|
98
|
+
private ProgressBar mapLoadingProgressBar;
|
|
99
|
+
private RelativeLayout mapLoadingLayout;
|
|
100
|
+
private ImageView cacheImageView;
|
|
101
|
+
private Boolean isMapLoaded = false;
|
|
102
|
+
private Integer loadingBackgroundColor = null;
|
|
103
|
+
private Integer loadingIndicatorColor = null;
|
|
104
|
+
|
|
105
|
+
private LatLngBounds boundsToMove;
|
|
106
|
+
private CameraUpdate cameraToSet;
|
|
107
|
+
private boolean setPaddingDeferred = false;
|
|
108
|
+
private boolean showUserLocation = false;
|
|
109
|
+
private boolean handlePanDrag = false;
|
|
110
|
+
private boolean moveOnMarkerPress = true;
|
|
111
|
+
private boolean cacheEnabled = false;
|
|
112
|
+
private boolean poiClickEnabled = true;
|
|
113
|
+
|
|
114
|
+
private ReadableMap initialRegion;
|
|
115
|
+
private ReadableMap region;
|
|
116
|
+
private ReadableMap initialCamera;
|
|
117
|
+
private ReadableMap camera;
|
|
118
|
+
private String customMapStyleString;
|
|
119
|
+
private boolean initialRegionSet = false;
|
|
120
|
+
private boolean initialCameraSet = false;
|
|
121
|
+
private LatLngBounds cameraLastIdleBounds;
|
|
122
|
+
private int cameraMoveReason = 0;
|
|
123
|
+
private MapMarker selectedMarker;
|
|
124
|
+
|
|
125
|
+
private static final String[] PERMISSIONS = new String[]{
|
|
126
|
+
"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"};
|
|
127
|
+
|
|
128
|
+
private final List<MapFeature> features = new ArrayList<>();
|
|
129
|
+
private final Map<Marker, MapMarker> markerMap = new HashMap<>();
|
|
130
|
+
private final Map<Polyline, MapPolyline> polylineMap = new HashMap<>();
|
|
131
|
+
private final Map<Polygon, MapPolygon> polygonMap = new HashMap<>();
|
|
132
|
+
private final Map<GroundOverlay, MapOverlay> overlayMap = new HashMap<>();
|
|
133
|
+
private final Map<TileOverlay, MapHeatmap> heatmapMap = new HashMap<>();
|
|
134
|
+
private final Map<TileOverlay, MapGradientPolyline> gradientPolylineMap = new HashMap<>();
|
|
135
|
+
private final GestureDetectorCompat gestureDetector;
|
|
136
|
+
private LifecycleEventListener lifecycleListener;
|
|
137
|
+
private boolean paused = false;
|
|
138
|
+
private boolean destroyed = false;
|
|
139
|
+
private final ThemedReactContext context;
|
|
140
|
+
private final FusedLocationSource fusedLocationSource;
|
|
141
|
+
|
|
142
|
+
private final ViewAttacherGroup attacherGroup;
|
|
143
|
+
private LatLng tapLocation;
|
|
144
|
+
private Float maxZoomLevel;
|
|
145
|
+
private Float minZoomLevel;
|
|
146
|
+
private Boolean pitchEnabled;
|
|
147
|
+
private Boolean showsCompass;
|
|
148
|
+
private Boolean rotateEnabled;
|
|
149
|
+
private Boolean zoomEnabled;
|
|
150
|
+
private Boolean zoomControlEnabled;
|
|
151
|
+
private Boolean setShowBuildings;
|
|
152
|
+
private Boolean showsIndoorLevelPicker;
|
|
153
|
+
private Boolean showIndoors;
|
|
154
|
+
private Boolean scrollEnabled;
|
|
155
|
+
private Boolean scrollDuringRotateOrZoomEnabled;
|
|
156
|
+
|
|
157
|
+
private static boolean contextHasBug(Context context) {
|
|
158
|
+
return context == null ||
|
|
159
|
+
context.getResources() == null ||
|
|
160
|
+
context.getResources().getConfiguration() == null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// We do this to fix this bug:
|
|
164
|
+
// https://github.com/react-native-maps/react-native-maps/issues/271
|
|
165
|
+
//
|
|
166
|
+
// which conflicts with another bug regarding the passed in context:
|
|
167
|
+
// https://github.com/react-native-maps/react-native-maps/issues/1147
|
|
168
|
+
//
|
|
169
|
+
// Doing this allows us to avoid both bugs.
|
|
170
|
+
private static Context getNonBuggyContext(ThemedReactContext reactContext,
|
|
171
|
+
ReactApplicationContext appContext) {
|
|
172
|
+
Context superContext = reactContext;
|
|
173
|
+
if (!contextHasBug(appContext.getCurrentActivity())) {
|
|
174
|
+
superContext = appContext.getCurrentActivity();
|
|
175
|
+
} else if (contextHasBug(superContext)) {
|
|
176
|
+
// we have the bug! let's try to find a better context to use
|
|
177
|
+
if (!contextHasBug(reactContext.getCurrentActivity())) {
|
|
178
|
+
superContext = reactContext.getCurrentActivity();
|
|
179
|
+
} else if (!contextHasBug(reactContext.getApplicationContext())) {
|
|
180
|
+
superContext = reactContext.getApplicationContext();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
return superContext;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public MapView(ThemedReactContext context,
|
|
188
|
+
GoogleMapOptions googleMapOptions) {
|
|
189
|
+
super(context, googleMapOptions);
|
|
190
|
+
// todo add support for legacy renderer
|
|
191
|
+
this.context = context;
|
|
192
|
+
super.onCreate(null);
|
|
193
|
+
super.onResume();
|
|
194
|
+
super.getMapAsync(this);
|
|
195
|
+
|
|
196
|
+
final MapView view = this;
|
|
197
|
+
|
|
198
|
+
fusedLocationSource = new FusedLocationSource(context);
|
|
199
|
+
|
|
200
|
+
gestureDetector =
|
|
201
|
+
new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
|
|
202
|
+
|
|
203
|
+
@Override
|
|
204
|
+
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
|
|
205
|
+
float distanceY) {
|
|
206
|
+
if (handlePanDrag) {
|
|
207
|
+
onPanDrag(e2);
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@Override
|
|
213
|
+
public boolean onDoubleTap(MotionEvent ev) {
|
|
214
|
+
onDoublePress(ev);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
this.addOnLayoutChangeListener(new OnLayoutChangeListener() {
|
|
220
|
+
@Override
|
|
221
|
+
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
|
222
|
+
int oldLeft, int oldTop, int oldRight, int oldBottom) {
|
|
223
|
+
if (!paused) {
|
|
224
|
+
MapView.this.cacheView();
|
|
204
225
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
// Set up a parent view for triggering visibility in subviews that depend on it.
|
|
231
|
+
// Mainly ReactImageView depends on Fresco which depends on onVisibilityChanged() event
|
|
232
|
+
attacherGroup = new ViewAttacherGroup(context);
|
|
233
|
+
LayoutParams attacherLayoutParams = new LayoutParams(0, 0);
|
|
234
|
+
attacherLayoutParams.width = 0;
|
|
235
|
+
attacherLayoutParams.height = 0;
|
|
236
|
+
attacherLayoutParams.leftMargin = 99999999;
|
|
237
|
+
attacherLayoutParams.topMargin = 99999999;
|
|
238
|
+
attacherGroup.setLayoutParams(attacherLayoutParams);
|
|
239
|
+
addView(attacherGroup);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public MapView(ThemedReactContext reactContext, ReactApplicationContext appContext,
|
|
243
|
+
MapManager manager,
|
|
244
|
+
GoogleMapOptions googleMapOptions) {
|
|
245
|
+
this(null, googleMapOptions);
|
|
246
|
+
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@FunctionalInterface
|
|
251
|
+
public interface EventCreator<T extends Event> {
|
|
252
|
+
T create(int surfaceId, int viewId, WritableMap payload);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private <T extends Event> void dispatchEvent(WritableMap payload, EventCreator<T> creator) {
|
|
256
|
+
// Cast context to ReactContext
|
|
257
|
+
ReactContext reactContext = context;
|
|
258
|
+
|
|
259
|
+
// Get the event dispatcher
|
|
260
|
+
EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, getId());
|
|
261
|
+
|
|
262
|
+
// If there is a dispatcher, create and dispatch the event
|
|
263
|
+
if (eventDispatcher != null) {
|
|
264
|
+
int surfaceId = UIManagerHelper.getSurfaceId(reactContext);
|
|
265
|
+
T event = creator.create(surfaceId, getId(), payload);
|
|
266
|
+
eventDispatcher.dispatchEvent(event);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@Override
|
|
271
|
+
public void onMapReady(@NonNull final GoogleMap map) {
|
|
272
|
+
if (destroyed) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.map = map;
|
|
276
|
+
if (maxZoomLevel != null) {
|
|
277
|
+
setMaxZoomLevel(maxZoomLevel);
|
|
278
|
+
}
|
|
279
|
+
if (minZoomLevel != null) {
|
|
280
|
+
setMinZoomLevel(minZoomLevel);
|
|
281
|
+
}
|
|
282
|
+
if (pitchEnabled != null) {
|
|
283
|
+
setPitchEnabled(pitchEnabled);
|
|
284
|
+
}
|
|
285
|
+
if (showsCompass != null) {
|
|
286
|
+
setShowsCompass(showsCompass);
|
|
287
|
+
}
|
|
288
|
+
if (rotateEnabled != null) {
|
|
289
|
+
setRotateEnabled(rotateEnabled);
|
|
290
|
+
}
|
|
291
|
+
if (zoomEnabled != null) {
|
|
292
|
+
setZoomEnabled(zoomEnabled);
|
|
293
|
+
}
|
|
294
|
+
if (zoomControlEnabled != null) {
|
|
295
|
+
setZoomControlEnabled(zoomControlEnabled);
|
|
296
|
+
}
|
|
297
|
+
if (setShowBuildings != null) {
|
|
298
|
+
setShowBuildings(setShowBuildings);
|
|
299
|
+
}
|
|
300
|
+
if (showsIndoorLevelPicker != null) {
|
|
301
|
+
setShowsIndoorLevelPicker(showsIndoorLevelPicker);
|
|
302
|
+
}
|
|
303
|
+
if (showIndoors != null) {
|
|
304
|
+
setShowIndoors(showIndoors);
|
|
305
|
+
}
|
|
306
|
+
if (scrollEnabled != null) {
|
|
307
|
+
setScrollEnabled(scrollEnabled);
|
|
308
|
+
}
|
|
309
|
+
if (scrollDuringRotateOrZoomEnabled != null) {
|
|
310
|
+
setScrollDuringRotateOrZoomEnabled(scrollDuringRotateOrZoomEnabled);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
markerManager = new MarkerManager(map);
|
|
314
|
+
markerCollection = markerManager.newCollection();
|
|
315
|
+
polylineManager = new PolylineManager(map);
|
|
316
|
+
polylineCollection = polylineManager.newCollection();
|
|
317
|
+
polygonManager = new PolygonManager(map);
|
|
318
|
+
polygonCollection = polygonManager.newCollection();
|
|
319
|
+
CircleManager circleManager = new CircleManager(map);
|
|
320
|
+
circleCollection = circleManager.newCollection();
|
|
321
|
+
groundOverlayManager = new GroundOverlayManager(map);
|
|
322
|
+
groundOverlayCollection = groundOverlayManager.newCollection();
|
|
323
|
+
|
|
324
|
+
markerCollection.setInfoWindowAdapter(this);
|
|
325
|
+
markerCollection.setOnMarkerDragListener(this);
|
|
326
|
+
this.map.setOnIndoorStateChangeListener(this);
|
|
327
|
+
|
|
328
|
+
applyBridgedProps();
|
|
329
|
+
dispatchEvent(new WritableNativeMap(), OnMapReadyEvent::new);
|
|
330
|
+
|
|
331
|
+
final MapView view = this;
|
|
332
|
+
|
|
333
|
+
map.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
|
|
334
|
+
@Override
|
|
335
|
+
public void onMyLocationChange(Location location) {
|
|
336
|
+
WritableMap event = new WritableNativeMap();
|
|
337
|
+
|
|
338
|
+
WritableMap coordinate = new WritableNativeMap();
|
|
339
|
+
coordinate.putDouble("latitude", location.getLatitude());
|
|
340
|
+
coordinate.putDouble("longitude", location.getLongitude());
|
|
341
|
+
coordinate.putDouble("altitude", location.getAltitude());
|
|
342
|
+
coordinate.putDouble("timestamp", location.getTime());
|
|
343
|
+
coordinate.putDouble("accuracy", location.getAccuracy());
|
|
344
|
+
coordinate.putDouble("speed", location.getSpeed());
|
|
345
|
+
coordinate.putDouble("heading", location.getBearing());
|
|
346
|
+
coordinate.putBoolean("isFromMockProvider", location.isFromMockProvider());
|
|
347
|
+
|
|
348
|
+
event.putMap("coordinate", coordinate);
|
|
349
|
+
dispatchEvent(event, OnUserLocationChangeEvent::new);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
markerCollection.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
|
|
354
|
+
@Override
|
|
355
|
+
public boolean onMarkerClick(@NonNull Marker marker) {
|
|
356
|
+
MapMarker airMapMarker = getMarkerMap(marker);
|
|
357
|
+
|
|
358
|
+
WritableMap eventData = makeClickEventData(marker.getPosition());
|
|
359
|
+
eventData.putString("action", "marker-press");
|
|
360
|
+
eventData.putString("id", airMapMarker.getIdentifier());
|
|
361
|
+
|
|
362
|
+
dispatchEvent(eventData, OnMarkerPressEvent::new);
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
eventData = makeClickEventData(marker.getPosition());
|
|
366
|
+
eventData.putString("action", "marker-press");
|
|
367
|
+
eventData.putString("id", airMapMarker.getIdentifier());
|
|
368
|
+
|
|
369
|
+
dispatchEvent(eventData, OnPressEvent::new);
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
handleMarkerSelection(airMapMarker);
|
|
373
|
+
|
|
374
|
+
// Return false to open the callout info window and center on the marker
|
|
375
|
+
// https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap
|
|
376
|
+
// .OnMarkerClickListener
|
|
377
|
+
if (view.moveOnMarkerPress) {
|
|
378
|
+
return false;
|
|
379
|
+
} else {
|
|
380
|
+
marker.showInfoWindow();
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
polygonCollection.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
|
|
387
|
+
@Override
|
|
388
|
+
public void onPolygonClick(@NonNull Polygon polygon) {
|
|
389
|
+
WritableMap event = makeClickEventData(tapLocation);
|
|
390
|
+
event.putString("action", "polygon-press");
|
|
391
|
+
// todo: use Fabric events
|
|
392
|
+
// manager.pushEvent(context, polygonMap.get(polygon), "onPress", event);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
polylineCollection.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
|
|
397
|
+
@Override
|
|
398
|
+
public void onPolylineClick(@NonNull Polyline polyline) {
|
|
399
|
+
WritableMap event = makeClickEventData(tapLocation);
|
|
400
|
+
event.putString("action", "polyline-press");
|
|
401
|
+
// todo: use Fabric events
|
|
402
|
+
// manager.pushEvent(context, polylineMap.get(polyline), "onPress", event);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
markerCollection.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
|
|
407
|
+
@Override
|
|
408
|
+
public void onInfoWindowClick(@NonNull Marker marker) {
|
|
409
|
+
WritableMap event = makeClickEventData(marker.getPosition());
|
|
410
|
+
event.putString("action", "callout-press");
|
|
411
|
+
// todo: use Fabric events
|
|
412
|
+
// manager.pushEvent(context, view, "onCalloutPress", event);
|
|
413
|
+
|
|
414
|
+
event = makeClickEventData(marker.getPosition());
|
|
415
|
+
event.putString("action", "callout-press");
|
|
416
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
417
|
+
// todo: use Fabric events
|
|
418
|
+
// manager.pushEvent(context, markerView, "onCalloutPress", event);
|
|
419
|
+
|
|
420
|
+
event = makeClickEventData(marker.getPosition());
|
|
421
|
+
event.putString("action", "callout-press");
|
|
422
|
+
MapCallout infoWindow = markerView.getCalloutView();
|
|
423
|
+
// todo: use Fabric events
|
|
424
|
+
// if (infoWindow != null) manager.pushEvent(context, infoWindow, "onPress", event);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
|
|
429
|
+
@Override
|
|
430
|
+
public void onMapClick(@NonNull LatLng point) {
|
|
431
|
+
WritableMap event = makeClickEventData(point);
|
|
432
|
+
event.putString("action", "press");
|
|
433
|
+
dispatchEvent(event, OnPressEvent::new);
|
|
434
|
+
|
|
435
|
+
handleMarkerSelection(null);
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
|
|
440
|
+
@Override
|
|
441
|
+
public void onMapLongClick(@NonNull LatLng point) {
|
|
442
|
+
WritableMap event = makeClickEventData(point);
|
|
443
|
+
event.putString("action", "long-press");
|
|
444
|
+
dispatchEvent(event, OnLongPressEvent::new);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
groundOverlayCollection.setOnGroundOverlayClickListener(new GoogleMap.OnGroundOverlayClickListener() {
|
|
449
|
+
@Override
|
|
450
|
+
public void onGroundOverlayClick(@NonNull GroundOverlay groundOverlay) {
|
|
451
|
+
WritableMap event = makeClickEventData(groundOverlay.getPosition());
|
|
452
|
+
event.putString("action", "overlay-press");
|
|
453
|
+
// todo: use Fabric events
|
|
454
|
+
// manager.pushEvent(context, overlayMap.get(groundOverlay), "onPress", event);
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
map.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
|
|
459
|
+
@Override
|
|
460
|
+
public void onCameraMoveStarted(int reason) {
|
|
461
|
+
cameraMoveReason = reason;
|
|
462
|
+
boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == reason;
|
|
463
|
+
WritableMap event = new WritableNativeMap();
|
|
464
|
+
event.putBoolean("isGesture", isGesture);
|
|
465
|
+
// todo: use Fabric events
|
|
466
|
+
// manager.pushEvent(context, view, "onRegionChangeStart", event);
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
|
|
471
|
+
@Override
|
|
472
|
+
public void onCameraMove() {
|
|
473
|
+
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
|
|
474
|
+
|
|
475
|
+
cameraLastIdleBounds = null;
|
|
476
|
+
boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason;
|
|
477
|
+
WritableMap payload = OnRegionChangeEvent.payLoadFor(bounds, true, isGesture);
|
|
478
|
+
dispatchEvent(payload, OnRegionChangeEvent::new);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
map.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
|
|
483
|
+
@Override
|
|
484
|
+
public void onCameraIdle() {
|
|
485
|
+
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
|
|
486
|
+
if ((cameraMoveReason != 0) &&
|
|
487
|
+
((cameraLastIdleBounds == null) ||
|
|
488
|
+
LatLngBoundsUtils.BoundsAreDifferent(bounds, cameraLastIdleBounds))) {
|
|
489
|
+
|
|
490
|
+
cameraLastIdleBounds = bounds;
|
|
491
|
+
boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason;
|
|
492
|
+
|
|
493
|
+
RegionChangeEvent event = new RegionChangeEvent(getId(), bounds, false, isGesture);
|
|
494
|
+
// todo: use Fabric events
|
|
495
|
+
// eventDispatcher.dispatchEvent(event);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
|
|
501
|
+
@Override
|
|
502
|
+
public void onMapLoaded() {
|
|
503
|
+
isMapLoaded = true;
|
|
504
|
+
// todo: use Fabric events
|
|
505
|
+
// manager.pushEvent(context, view, "onMapLoaded", new WritableNativeMap());
|
|
506
|
+
MapView.this.cacheView();
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
// We need to be sure to disable location-tracking when app enters background, in-case some
|
|
511
|
+
// other module
|
|
512
|
+
// has acquired a wake-lock and is controlling location-updates, otherwise, location-manager
|
|
513
|
+
// will be left
|
|
514
|
+
// updating location constantly, killing the battery, even though some other location-mgmt
|
|
515
|
+
// module may
|
|
516
|
+
// desire to shut-down location-services.
|
|
517
|
+
lifecycleListener = new LifecycleEventListener() {
|
|
518
|
+
@Override
|
|
519
|
+
public void onHostResume() {
|
|
520
|
+
if (hasPermissions() && map != null) {
|
|
521
|
+
//noinspection MissingPermission
|
|
522
|
+
map.setMyLocationEnabled(showUserLocation);
|
|
523
|
+
map.setLocationSource(fusedLocationSource);
|
|
524
|
+
}
|
|
525
|
+
synchronized (MapView.this) {
|
|
526
|
+
if (!destroyed) {
|
|
527
|
+
MapView.this.onResume();
|
|
528
|
+
}
|
|
529
|
+
paused = false;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
@Override
|
|
534
|
+
public void onHostPause() {
|
|
535
|
+
if (hasPermissions() && map != null) {
|
|
536
|
+
//noinspection MissingPermission
|
|
537
|
+
map.setMyLocationEnabled(false);
|
|
538
|
+
}
|
|
539
|
+
synchronized (MapView.this) {
|
|
540
|
+
if (!destroyed) {
|
|
541
|
+
MapView.this.onPause();
|
|
542
|
+
}
|
|
543
|
+
paused = true;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
@Override
|
|
548
|
+
public void onHostDestroy() {
|
|
549
|
+
MapView.this.doDestroy();
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
context.addLifecycleEventListener(lifecycleListener);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
private synchronized void handleMarkerSelection(MapMarker target) {
|
|
557
|
+
if (selectedMarker == target) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
WritableMap event;
|
|
562
|
+
|
|
563
|
+
if (selectedMarker != null) {
|
|
564
|
+
event = makeClickEventData(selectedMarker.getPosition());
|
|
565
|
+
event.putString("action", "marker-deselect");
|
|
566
|
+
event.putString("id", selectedMarker.getIdentifier());
|
|
567
|
+
// todo: use Fabric events
|
|
568
|
+
// manager.pushEvent(context, selectedMarker, "onDeselect", event);
|
|
569
|
+
|
|
570
|
+
event = makeClickEventData(selectedMarker.getPosition());
|
|
571
|
+
event.putString("action", "marker-deselect");
|
|
572
|
+
event.putString("id", selectedMarker.getIdentifier());
|
|
573
|
+
dispatchEvent(event, OnMarkerDeselectEvent::new);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (target != null) {
|
|
577
|
+
event = makeClickEventData(target.getPosition());
|
|
578
|
+
event.putString("action", "marker-select");
|
|
579
|
+
event.putString("id", target.getIdentifier());
|
|
580
|
+
// todo: use Fabric events
|
|
581
|
+
// manager.pushEvent(context, target, "onSelect", event);
|
|
582
|
+
|
|
583
|
+
event = makeClickEventData(target.getPosition());
|
|
584
|
+
event.putString("action", "marker-select");
|
|
585
|
+
event.putString("id", target.getIdentifier());
|
|
586
|
+
dispatchEvent(event, OnMarkerSelectEvent::new);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
selectedMarker = target;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
private boolean hasPermissions() {
|
|
593
|
+
return checkSelfPermission(getContext(), PERMISSIONS[0]) == PermissionChecker.PERMISSION_GRANTED ||
|
|
594
|
+
checkSelfPermission(getContext(), PERMISSIONS[1]) == PermissionChecker.PERMISSION_GRANTED;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
public static Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
|
|
599
|
+
MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
|
|
600
|
+
builder.put(OnMarkerPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerPressEvent.EVENT_NAME));
|
|
601
|
+
builder.put(OnPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPressEvent.EVENT_NAME));
|
|
602
|
+
builder.put(OnMarkerSelectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerSelectEvent.EVENT_NAME));
|
|
603
|
+
builder.put(OnMarkerDeselectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDeselectEvent.EVENT_NAME));
|
|
604
|
+
builder.put(OnMarkerDragEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEvent.EVENT_NAME));
|
|
605
|
+
builder.put(OnMarkerDragStartEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragStartEvent.EVENT_NAME));
|
|
606
|
+
builder.put(OnMarkerDragEndEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEndEvent.EVENT_NAME));
|
|
607
|
+
builder.put(OnPoiClickEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPoiClickEvent.EVENT_NAME));
|
|
608
|
+
builder.put(OnLongPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnLongPressEvent.EVENT_NAME));
|
|
609
|
+
return builder.build();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
public static Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
613
|
+
return MapBuilder.of(
|
|
614
|
+
OnMapReadyEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMapReadyEvent.EVENT_NAME),
|
|
615
|
+
OnUserLocationChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnUserLocationChangeEvent.EVENT_NAME),
|
|
616
|
+
OnRegionChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnRegionChangeEvent.EVENT_NAME)
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
/*
|
|
622
|
+
onDestroy is final method so I can't override it.
|
|
623
|
+
*/
|
|
624
|
+
public synchronized void doDestroy() {
|
|
625
|
+
if (destroyed) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
destroyed = true;
|
|
629
|
+
|
|
630
|
+
if (lifecycleListener != null && context != null) {
|
|
631
|
+
context.removeLifecycleEventListener(lifecycleListener);
|
|
632
|
+
lifecycleListener = null;
|
|
633
|
+
}
|
|
218
634
|
if (!paused) {
|
|
219
|
-
|
|
635
|
+
onPause();
|
|
636
|
+
paused = true;
|
|
220
637
|
}
|
|
221
|
-
|
|
222
|
-
}
|
|
638
|
+
onDestroy();
|
|
639
|
+
}
|
|
223
640
|
|
|
641
|
+
public void setInitialCameraSet(boolean initialCameraSet) {
|
|
642
|
+
this.initialCameraSet = initialCameraSet;
|
|
643
|
+
}
|
|
224
644
|
|
|
645
|
+
public void setInitialRegion(ReadableMap initialRegion) {
|
|
646
|
+
this.initialRegion = initialRegion;
|
|
647
|
+
// Theoretically onMapReady might be called before setInitialRegion
|
|
648
|
+
// In that case, trigger moveToRegion manually
|
|
649
|
+
if (!initialRegionSet && map != null) {
|
|
650
|
+
moveToRegion(initialRegion);
|
|
651
|
+
initialRegionSet = true;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
225
654
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
attacherLayoutParams.topMargin = 99999999;
|
|
234
|
-
attacherGroup.setLayoutParams(attacherLayoutParams);
|
|
235
|
-
addView(attacherGroup);
|
|
236
|
-
}
|
|
655
|
+
public void setInitialCamera(ReadableMap initialCamera) {
|
|
656
|
+
this.initialCamera = initialCamera;
|
|
657
|
+
if (!initialCameraSet && map != null) {
|
|
658
|
+
moveToCamera(initialCamera);
|
|
659
|
+
initialCameraSet = true;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
237
662
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
663
|
+
private void applyBridgedProps() {
|
|
664
|
+
if (initialRegion != null) {
|
|
665
|
+
moveToRegion(initialRegion);
|
|
666
|
+
initialRegionSet = true;
|
|
667
|
+
} else if (region != null) {
|
|
668
|
+
moveToRegion(region);
|
|
669
|
+
} else if (initialCamera != null) {
|
|
670
|
+
moveToCamera(initialCamera);
|
|
671
|
+
initialCameraSet = true;
|
|
672
|
+
} else if (camera != null) {
|
|
673
|
+
moveToCamera(camera);
|
|
674
|
+
}
|
|
675
|
+
if (customMapStyleString != null) {
|
|
676
|
+
map.setMapStyle(new MapStyleOptions(customMapStyleString));
|
|
677
|
+
}
|
|
678
|
+
this.setPoiClickEnabled(poiClickEnabled);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
public static LatLngBounds latLngBoundsFromRegion(ReadableMap region) {
|
|
682
|
+
if (region == null) return null;
|
|
683
|
+
|
|
684
|
+
double lng = region.getDouble("longitude");
|
|
685
|
+
double lat = region.getDouble("latitude");
|
|
686
|
+
double lngDelta = region.getDouble("longitudeDelta");
|
|
687
|
+
double latDelta = region.getDouble("latitudeDelta");
|
|
688
|
+
return new LatLngBounds(
|
|
689
|
+
new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest
|
|
690
|
+
new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
private void moveToRegion(ReadableMap region) {
|
|
695
|
+
LatLngBounds bounds = latLngBoundsFromRegion(region);
|
|
696
|
+
if (bounds == null) return;
|
|
697
|
+
double lng = region.getDouble("longitude");
|
|
698
|
+
double lat = region.getDouble("latitude");
|
|
699
|
+
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
700
|
+
// in this case, our map has not been laid out yet, so we save the bounds in a local
|
|
701
|
+
// variable, and make a guess of zoomLevel 10. Not to worry, though: as soon as layout
|
|
702
|
+
// occurs, we will move the camera to the saved bounds. Note that if we tried to move
|
|
703
|
+
// to the bounds now, it would trigger an exception.
|
|
704
|
+
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10));
|
|
705
|
+
boundsToMove = bounds;
|
|
706
|
+
} else {
|
|
707
|
+
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
|
|
708
|
+
boundsToMove = null;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
242
711
|
|
|
243
|
-
|
|
712
|
+
public void setRegion(ReadableMap region) {
|
|
713
|
+
this.region = region;
|
|
714
|
+
if (region != null && map != null) {
|
|
715
|
+
moveToRegion(region);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
244
718
|
|
|
719
|
+
public void setCamera(ReadableMap camera) {
|
|
720
|
+
this.camera = camera;
|
|
721
|
+
if (camera != null && map != null) {
|
|
722
|
+
moveToCamera(camera);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
public static CameraPosition cameraPositionFromMap(ReadableMap camera) {
|
|
727
|
+
if (camera == null) return null;
|
|
245
728
|
|
|
246
|
-
|
|
247
|
-
public interface EventCreator<T extends Event> {
|
|
248
|
-
T create(int surfaceId, int viewId, WritableMap payload);
|
|
249
|
-
}
|
|
250
|
-
private <T extends Event> void dispatchEvent(WritableMap payload, EventCreator<T> creator) {
|
|
251
|
-
// Cast context to ReactContext
|
|
252
|
-
ReactContext reactContext = context;
|
|
729
|
+
CameraPosition.Builder builder = new CameraPosition.Builder();
|
|
253
730
|
|
|
254
|
-
|
|
255
|
-
|
|
731
|
+
ReadableMap center = camera.getMap("center");
|
|
732
|
+
if (center != null) {
|
|
733
|
+
double lng = center.getDouble("longitude");
|
|
734
|
+
double lat = center.getDouble("latitude");
|
|
735
|
+
builder.target(new LatLng(lat, lng));
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
builder.tilt((float) camera.getDouble("pitch"));
|
|
739
|
+
builder.bearing((float) camera.getDouble("heading"));
|
|
740
|
+
builder.zoom((float) camera.getDouble("zoom"));
|
|
256
741
|
|
|
257
|
-
|
|
258
|
-
if (eventDispatcher != null) {
|
|
259
|
-
int surfaceId = UIManagerHelper.getSurfaceId(reactContext);
|
|
260
|
-
T event = creator.create(surfaceId, getId(), payload);
|
|
261
|
-
eventDispatcher.dispatchEvent(event);
|
|
742
|
+
return builder.build();
|
|
262
743
|
}
|
|
263
|
-
}
|
|
264
744
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
745
|
+
public CameraPosition cameraPositionFromJSON(JSONObject camera) throws JSONException {
|
|
746
|
+
if (camera == null) return null;
|
|
747
|
+
if (map == null) return null;
|
|
748
|
+
|
|
749
|
+
CameraPosition.Builder builder = new CameraPosition.Builder();
|
|
750
|
+
|
|
751
|
+
if (camera.has("center")) {
|
|
752
|
+
JSONObject center = camera.getJSONObject("center");
|
|
753
|
+
if (center != null) {
|
|
754
|
+
double lng = center.getDouble("longitude");
|
|
755
|
+
double lat = center.getDouble("latitude");
|
|
756
|
+
builder.target(new LatLng(lat, lng));
|
|
757
|
+
}
|
|
758
|
+
} else {
|
|
759
|
+
builder.target(map.getCameraPosition().target);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
if (camera.has("pitch")) {
|
|
763
|
+
builder.tilt((float) camera.getDouble("pitch"));
|
|
764
|
+
} else {
|
|
765
|
+
builder.tilt(map.getCameraPosition().tilt);
|
|
766
|
+
}
|
|
767
|
+
if (camera.has("heading")) {
|
|
768
|
+
builder.bearing((float) camera.getDouble("heading"));
|
|
769
|
+
} else {
|
|
770
|
+
builder.bearing(map.getCameraPosition().bearing);
|
|
771
|
+
}
|
|
772
|
+
if (camera.has("zoom")) {
|
|
773
|
+
builder.zoom((float) camera.getDouble("zoom"));
|
|
774
|
+
} else {
|
|
775
|
+
builder.zoom(map.getCameraPosition().zoom);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
return builder.build();
|
|
269
779
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
780
|
+
|
|
781
|
+
public void moveToCamera(ReadableMap cameraMap) {
|
|
782
|
+
moveToCamera(cameraPositionFromMap(cameraMap));
|
|
273
783
|
}
|
|
274
|
-
|
|
275
|
-
|
|
784
|
+
|
|
785
|
+
public void moveToCamera(CameraPosition camera) {
|
|
786
|
+
if (camera == null) return;
|
|
787
|
+
CameraUpdate update = CameraUpdateFactory.newCameraPosition(camera);
|
|
788
|
+
|
|
789
|
+
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
790
|
+
// in this case, our map has not been laid out yet, so we save the camera update in a
|
|
791
|
+
// local variable. As soon as layout occurs, we will move the camera to the saved update.
|
|
792
|
+
// Note that if we tried to move to the camera now, it would trigger an exception.
|
|
793
|
+
cameraToSet = update;
|
|
794
|
+
} else {
|
|
795
|
+
map.moveCamera(update);
|
|
796
|
+
cameraToSet = null;
|
|
797
|
+
}
|
|
276
798
|
}
|
|
277
|
-
|
|
278
|
-
|
|
799
|
+
|
|
800
|
+
public void setMapStyle(@Nullable String customMapStyleString) {
|
|
801
|
+
this.customMapStyleString = customMapStyleString;
|
|
802
|
+
if (map != null && customMapStyleString != null) {
|
|
803
|
+
map.setMapStyle(new MapStyleOptions(customMapStyleString));
|
|
804
|
+
}
|
|
279
805
|
}
|
|
280
|
-
|
|
281
|
-
|
|
806
|
+
|
|
807
|
+
public void setShowsUserLocation(boolean showUserLocation) {
|
|
808
|
+
this.showUserLocation = showUserLocation; // hold onto this for lifecycle handling
|
|
809
|
+
if (hasPermissions()) {
|
|
810
|
+
map.setLocationSource(fusedLocationSource);
|
|
811
|
+
//noinspection MissingPermission
|
|
812
|
+
map.setMyLocationEnabled(showUserLocation);
|
|
813
|
+
}
|
|
282
814
|
}
|
|
283
|
-
|
|
284
|
-
|
|
815
|
+
|
|
816
|
+
public void setUserLocationPriority(int priority) {
|
|
817
|
+
fusedLocationSource.setPriority(priority);
|
|
285
818
|
}
|
|
286
|
-
|
|
287
|
-
|
|
819
|
+
|
|
820
|
+
public void setUserLocationUpdateInterval(int interval) {
|
|
821
|
+
fusedLocationSource.setInterval(interval);
|
|
288
822
|
}
|
|
289
|
-
|
|
290
|
-
|
|
823
|
+
|
|
824
|
+
public void setUserLocationFastestInterval(int interval) {
|
|
825
|
+
fusedLocationSource.setFastestInterval(interval);
|
|
291
826
|
}
|
|
292
|
-
|
|
293
|
-
|
|
827
|
+
|
|
828
|
+
public void setShowsMyLocationButton(boolean showMyLocationButton) {
|
|
829
|
+
if (map != null) {
|
|
830
|
+
if (hasPermissions() || !showMyLocationButton) {
|
|
831
|
+
map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
294
834
|
}
|
|
295
|
-
|
|
296
|
-
|
|
835
|
+
|
|
836
|
+
public void setToolbarEnabled(boolean toolbarEnabled) {
|
|
837
|
+
if (map != null) {
|
|
838
|
+
if (hasPermissions() || !toolbarEnabled) {
|
|
839
|
+
map.getUiSettings().setMapToolbarEnabled(toolbarEnabled);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
297
842
|
}
|
|
298
|
-
|
|
299
|
-
|
|
843
|
+
|
|
844
|
+
public void setMapType(int mapType) {
|
|
845
|
+
if (map != null) {
|
|
846
|
+
map.setMapType(mapType);
|
|
847
|
+
}
|
|
300
848
|
}
|
|
301
|
-
|
|
302
|
-
|
|
849
|
+
|
|
850
|
+
public void setCacheEnabled(boolean cacheEnabled) {
|
|
851
|
+
this.cacheEnabled = cacheEnabled;
|
|
852
|
+
this.cacheView();
|
|
303
853
|
}
|
|
304
|
-
|
|
305
|
-
|
|
854
|
+
|
|
855
|
+
public void setPoiClickEnabled(boolean poiClickEnabled) {
|
|
856
|
+
this.poiClickEnabled = poiClickEnabled;
|
|
857
|
+
if (map != null) {
|
|
858
|
+
map.setOnPoiClickListener(poiClickEnabled ? this : null);
|
|
859
|
+
}
|
|
306
860
|
}
|
|
307
861
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
polygonCollection = polygonManager.newCollection();
|
|
314
|
-
CircleManager circleManager = new CircleManager(map);
|
|
315
|
-
circleCollection = circleManager.newCollection();
|
|
316
|
-
groundOverlayManager = new GroundOverlayManager(map);
|
|
317
|
-
groundOverlayCollection = groundOverlayManager.newCollection();
|
|
862
|
+
public void setLoadingEnabled(boolean loadingEnabled) {
|
|
863
|
+
if (loadingEnabled && !this.isMapLoaded) {
|
|
864
|
+
this.getMapLoadingLayoutView().setVisibility(View.VISIBLE);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
318
867
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
868
|
+
public void setMoveOnMarkerPress(boolean moveOnPress) {
|
|
869
|
+
this.moveOnMarkerPress = moveOnPress;
|
|
870
|
+
}
|
|
322
871
|
|
|
323
|
-
|
|
324
|
-
|
|
872
|
+
public void setMaxZoomLevel(float maxZoomLevel) {
|
|
873
|
+
this.maxZoomLevel = maxZoomLevel;
|
|
874
|
+
if (map != null) {
|
|
875
|
+
map.setMaxZoomPreference(maxZoomLevel);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
325
878
|
|
|
326
|
-
|
|
879
|
+
public void setMinZoomLevel(float minZoomLevel) {
|
|
880
|
+
this.minZoomLevel = minZoomLevel;
|
|
881
|
+
if (map != null) {
|
|
882
|
+
map.setMinZoomPreference(minZoomLevel);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
327
885
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
886
|
+
public void setPitchEnabled(boolean pitchEnabled) {
|
|
887
|
+
this.pitchEnabled = pitchEnabled;
|
|
888
|
+
if (map != null) {
|
|
889
|
+
map.getUiSettings().setTiltGesturesEnabled(pitchEnabled);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
332
892
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
coordinate.putDouble("speed", location.getSpeed());
|
|
340
|
-
coordinate.putDouble("heading", location.getBearing());
|
|
341
|
-
coordinate.putBoolean("isFromMockProvider", location.isFromMockProvider());
|
|
893
|
+
public void setShowsCompass(boolean showsCompass) {
|
|
894
|
+
this.showsCompass = showsCompass;
|
|
895
|
+
if (map != null) {
|
|
896
|
+
map.getUiSettings().setCompassEnabled(showsCompass);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
342
899
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
900
|
+
public void setRotateEnabled(boolean rotateEnabled) {
|
|
901
|
+
this.rotateEnabled = rotateEnabled;
|
|
902
|
+
if (map != null) {
|
|
903
|
+
map.getUiSettings().setRotateGesturesEnabled(rotateEnabled);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
347
906
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
907
|
+
public void setZoomEnabled(boolean zoomEnabled) {
|
|
908
|
+
this.zoomEnabled = zoomEnabled;
|
|
909
|
+
if (map != null) {
|
|
910
|
+
map.getUiSettings().setZoomGesturesEnabled(zoomEnabled);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
352
913
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
914
|
+
public void setZoomControlEnabled(boolean zoomControlEnabled) {
|
|
915
|
+
this.zoomControlEnabled = zoomControlEnabled;
|
|
916
|
+
if (map != null) {
|
|
917
|
+
map.getUiSettings().setZoomControlsEnabled(zoomControlEnabled);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
356
920
|
|
|
357
|
-
|
|
921
|
+
public void setScrollDuringRotateOrZoomEnabled(boolean scrollDuringRotateOrZoomEnabled) {
|
|
922
|
+
this.scrollDuringRotateOrZoomEnabled = scrollDuringRotateOrZoomEnabled;
|
|
923
|
+
if (map != null) {
|
|
924
|
+
map.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringRotateOrZoomEnabled);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
358
927
|
|
|
928
|
+
public void setScrollEnabled(boolean scrollEnabled) {
|
|
929
|
+
this.scrollEnabled = scrollEnabled;
|
|
930
|
+
if (map != null) {
|
|
931
|
+
map.getUiSettings().setScrollGesturesEnabled(scrollEnabled);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
359
934
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
935
|
+
public void setShowIndoors(boolean showIndoors) {
|
|
936
|
+
this.showIndoors = showIndoors;
|
|
937
|
+
if (map != null) {
|
|
938
|
+
map.setIndoorEnabled(showIndoors);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
363
941
|
|
|
364
|
-
|
|
942
|
+
public void setShowsIndoorLevelPicker(boolean showsIndoorLevelPicker) {
|
|
943
|
+
this.showsIndoorLevelPicker = showsIndoorLevelPicker;
|
|
944
|
+
if (map != null) {
|
|
945
|
+
map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
public void setShowBuildings(boolean showBuildings) {
|
|
950
|
+
this.setShowBuildings = showBuildings;
|
|
951
|
+
if (map != null) {
|
|
952
|
+
map.setBuildingsEnabled(showBuildings);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
365
955
|
|
|
366
956
|
|
|
367
|
-
|
|
957
|
+
public void setLoadingBackgroundColor(Integer loadingBackgroundColor) {
|
|
958
|
+
this.loadingBackgroundColor = loadingBackgroundColor;
|
|
368
959
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
960
|
+
if (this.mapLoadingLayout != null) {
|
|
961
|
+
if (loadingBackgroundColor == null) {
|
|
962
|
+
this.mapLoadingLayout.setBackgroundColor(Color.WHITE);
|
|
963
|
+
} else {
|
|
964
|
+
this.mapLoadingLayout.setBackgroundColor(this.loadingBackgroundColor);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
public void setLoadingIndicatorColor(Integer loadingIndicatorColor) {
|
|
970
|
+
this.loadingIndicatorColor = loadingIndicatorColor;
|
|
971
|
+
if (this.mapLoadingProgressBar != null) {
|
|
972
|
+
Integer color = loadingIndicatorColor;
|
|
973
|
+
if (color == null) {
|
|
974
|
+
color = Color.parseColor("#606060");
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
ColorStateList progressTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
978
|
+
ColorStateList secondaryProgressTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
979
|
+
ColorStateList indeterminateTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
980
|
+
|
|
981
|
+
this.mapLoadingProgressBar.setProgressTintList(progressTintList);
|
|
982
|
+
this.mapLoadingProgressBar.setSecondaryProgressTintList(secondaryProgressTintList);
|
|
983
|
+
this.mapLoadingProgressBar.setIndeterminateTintList(indeterminateTintList);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
public void setHandlePanDrag(boolean handlePanDrag) {
|
|
988
|
+
this.handlePanDrag = handlePanDrag;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
public void addFeature(View child, int index) {
|
|
992
|
+
// Our desired API is to pass up annotations/overlays as children to the mapview component.
|
|
993
|
+
// This is where we intercept them and do the appropriate underlying mapview action.
|
|
994
|
+
if (child instanceof MapMarker) {
|
|
995
|
+
MapMarker annotation = (MapMarker) child;
|
|
996
|
+
annotation.addToMap(markerCollection);
|
|
997
|
+
features.add(index, annotation);
|
|
998
|
+
|
|
999
|
+
// Allow visibility event to be triggered later
|
|
1000
|
+
int visibility = annotation.getVisibility();
|
|
1001
|
+
annotation.setVisibility(INVISIBLE);
|
|
1002
|
+
|
|
1003
|
+
// Remove from a view group if already present, prevent "specified child
|
|
1004
|
+
// already had a parent" error.
|
|
1005
|
+
ViewGroup annotationParent = (ViewGroup) annotation.getParent();
|
|
1006
|
+
if (annotationParent != null) {
|
|
1007
|
+
annotationParent.removeView(annotation);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Add to the parent group
|
|
1011
|
+
attacherGroup.addView(annotation);
|
|
1012
|
+
|
|
1013
|
+
// Trigger visibility event if necessary.
|
|
1014
|
+
// With some testing, seems like it is not always
|
|
1015
|
+
// triggered just by being added to a parent view.
|
|
1016
|
+
annotation.setVisibility(visibility);
|
|
1017
|
+
|
|
1018
|
+
Marker marker = (Marker) annotation.getFeature();
|
|
1019
|
+
markerMap.put(marker, annotation);
|
|
1020
|
+
} else if (child instanceof MapPolyline) {
|
|
1021
|
+
MapPolyline polylineView = (MapPolyline) child;
|
|
1022
|
+
polylineView.addToMap(polylineCollection);
|
|
1023
|
+
features.add(index, polylineView);
|
|
1024
|
+
Polyline polyline = (Polyline) polylineView.getFeature();
|
|
1025
|
+
polylineMap.put(polyline, polylineView);
|
|
1026
|
+
} else if (child instanceof MapGradientPolyline) {
|
|
1027
|
+
MapGradientPolyline polylineView = (MapGradientPolyline) child;
|
|
1028
|
+
polylineView.addToMap(map);
|
|
1029
|
+
features.add(index, polylineView);
|
|
1030
|
+
TileOverlay tileOverlay = (TileOverlay) polylineView.getFeature();
|
|
1031
|
+
gradientPolylineMap.put(tileOverlay, polylineView);
|
|
1032
|
+
} else if (child instanceof MapPolygon) {
|
|
1033
|
+
MapPolygon polygonView = (MapPolygon) child;
|
|
1034
|
+
polygonView.addToMap(polygonCollection);
|
|
1035
|
+
features.add(index, polygonView);
|
|
1036
|
+
Polygon polygon = (Polygon) polygonView.getFeature();
|
|
1037
|
+
polygonMap.put(polygon, polygonView);
|
|
1038
|
+
} else if (child instanceof MapCircle) {
|
|
1039
|
+
MapCircle circleView = (MapCircle) child;
|
|
1040
|
+
circleView.addToMap(circleCollection);
|
|
1041
|
+
features.add(index, circleView);
|
|
1042
|
+
} else if (child instanceof MapUrlTile) {
|
|
1043
|
+
MapUrlTile urlTileView = (MapUrlTile) child;
|
|
1044
|
+
urlTileView.addToMap(map);
|
|
1045
|
+
features.add(index, urlTileView);
|
|
1046
|
+
} else if (child instanceof MapWMSTile) {
|
|
1047
|
+
MapWMSTile urlTileView = (MapWMSTile) child;
|
|
1048
|
+
urlTileView.addToMap(map);
|
|
1049
|
+
features.add(index, urlTileView);
|
|
1050
|
+
} else if (child instanceof MapLocalTile) {
|
|
1051
|
+
MapLocalTile localTileView = (MapLocalTile) child;
|
|
1052
|
+
localTileView.addToMap(map);
|
|
1053
|
+
features.add(index, localTileView);
|
|
1054
|
+
} else if (child instanceof MapOverlay) {
|
|
1055
|
+
MapOverlay overlayView = (MapOverlay) child;
|
|
1056
|
+
overlayView.addToMap(groundOverlayCollection);
|
|
1057
|
+
features.add(index, overlayView);
|
|
1058
|
+
GroundOverlay overlay = (GroundOverlay) overlayView.getFeature();
|
|
1059
|
+
overlayMap.put(overlay, overlayView);
|
|
1060
|
+
} else if (child instanceof MapHeatmap) {
|
|
1061
|
+
MapHeatmap heatmapView = (MapHeatmap) child;
|
|
1062
|
+
heatmapView.addToMap(map);
|
|
1063
|
+
features.add(index, heatmapView);
|
|
1064
|
+
TileOverlay heatmap = (TileOverlay) heatmapView.getFeature();
|
|
1065
|
+
heatmapMap.put(heatmap, heatmapView);
|
|
1066
|
+
} else if (child instanceof ViewGroup) {
|
|
1067
|
+
ViewGroup children = (ViewGroup) child;
|
|
1068
|
+
for (int i = 0; i < children.getChildCount(); i++) {
|
|
1069
|
+
addFeature(children.getChildAt(i), index);
|
|
1070
|
+
}
|
|
374
1071
|
} else {
|
|
375
|
-
|
|
376
|
-
return true;
|
|
1072
|
+
addView(child, index);
|
|
377
1073
|
}
|
|
378
|
-
|
|
379
|
-
});
|
|
1074
|
+
}
|
|
380
1075
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
WritableMap event = makeClickEventData(tapLocation);
|
|
385
|
-
event.putString("action", "polygon-press");
|
|
386
|
-
// todo: use Fabric events
|
|
387
|
-
// manager.pushEvent(context, polygonMap.get(polygon), "onPress", event);
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
polylineCollection.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
|
|
392
|
-
@Override
|
|
393
|
-
public void onPolylineClick(@NonNull Polyline polyline) {
|
|
394
|
-
WritableMap event = makeClickEventData(tapLocation);
|
|
395
|
-
event.putString("action", "polyline-press");
|
|
396
|
-
// todo: use Fabric events
|
|
397
|
-
// manager.pushEvent(context, polylineMap.get(polyline), "onPress", event);
|
|
398
|
-
}
|
|
399
|
-
});
|
|
1076
|
+
public int getFeatureCount() {
|
|
1077
|
+
return features.size();
|
|
1078
|
+
}
|
|
400
1079
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
WritableMap event = makeClickEventData(marker.getPosition());
|
|
405
|
-
event.putString("action", "callout-press");
|
|
406
|
-
// todo: use Fabric events
|
|
407
|
-
// manager.pushEvent(context, view, "onCalloutPress", event);
|
|
1080
|
+
public View getFeatureAt(int index) {
|
|
1081
|
+
return features.get(index);
|
|
1082
|
+
}
|
|
408
1083
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
1084
|
+
public void removeFeatureAt(int index) {
|
|
1085
|
+
MapFeature feature = features.remove(index);
|
|
1086
|
+
if (feature instanceof MapMarker) {
|
|
1087
|
+
markerMap.remove(feature.getFeature());
|
|
1088
|
+
feature.removeFromMap(markerCollection);
|
|
1089
|
+
attacherGroup.removeView(feature);
|
|
1090
|
+
} else if (feature instanceof MapHeatmap) {
|
|
1091
|
+
heatmapMap.remove(feature.getFeature());
|
|
1092
|
+
feature.removeFromMap(map);
|
|
1093
|
+
} else if (feature instanceof MapCircle) {
|
|
1094
|
+
feature.removeFromMap(circleCollection);
|
|
1095
|
+
} else if (feature instanceof MapOverlay) {
|
|
1096
|
+
feature.removeFromMap(groundOverlayCollection);
|
|
1097
|
+
} else if (feature instanceof MapPolygon) {
|
|
1098
|
+
feature.removeFromMap(polygonCollection);
|
|
1099
|
+
} else if (feature instanceof MapPolyline) {
|
|
1100
|
+
feature.removeFromMap(polylineCollection);
|
|
1101
|
+
} else {
|
|
1102
|
+
feature.removeFromMap(map);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
414
1105
|
|
|
415
|
-
|
|
416
|
-
event.putString("action", "callout-press");
|
|
417
|
-
MapCallout infoWindow = markerView.getCalloutView();
|
|
418
|
-
// todo: use Fabric events
|
|
419
|
-
// if (infoWindow != null) manager.pushEvent(context, infoWindow, "onPress", event);
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
|
|
424
|
-
@Override
|
|
425
|
-
public void onMapClick(@NonNull LatLng point) {
|
|
426
|
-
WritableMap event = makeClickEventData(point);
|
|
427
|
-
event.putString("action", "press");
|
|
428
|
-
dispatchEvent(event, OnPressEvent::new);
|
|
429
|
-
|
|
430
|
-
handleMarkerSelection(null);
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
|
|
435
|
-
@Override
|
|
436
|
-
public void onMapLongClick(@NonNull LatLng point) {
|
|
437
|
-
WritableMap event = makeClickEventData(point);
|
|
438
|
-
event.putString("action", "long-press");
|
|
439
|
-
dispatchEvent(event, OnLongPressEvent::new);
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
groundOverlayCollection.setOnGroundOverlayClickListener(new GoogleMap.OnGroundOverlayClickListener() {
|
|
444
|
-
@Override
|
|
445
|
-
public void onGroundOverlayClick(@NonNull GroundOverlay groundOverlay) {
|
|
446
|
-
WritableMap event = makeClickEventData(groundOverlay.getPosition());
|
|
447
|
-
event.putString("action", "overlay-press");
|
|
448
|
-
// todo: use Fabric events
|
|
449
|
-
// manager.pushEvent(context, overlayMap.get(groundOverlay), "onPress", event);
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
map.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
|
|
454
|
-
@Override
|
|
455
|
-
public void onCameraMoveStarted(int reason) {
|
|
456
|
-
cameraMoveReason = reason;
|
|
457
|
-
boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == reason;
|
|
1106
|
+
public WritableMap makeClickEventData(LatLng point) {
|
|
458
1107
|
WritableMap event = new WritableNativeMap();
|
|
459
|
-
event.putBoolean("isGesture", isGesture);
|
|
460
|
-
// todo: use Fabric events
|
|
461
|
-
// manager.pushEvent(context, view, "onRegionChangeStart", event);
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
|
|
466
|
-
@Override
|
|
467
|
-
public void onCameraMove() {
|
|
468
|
-
Log.e("MapView", "onCameraMove");
|
|
469
|
-
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
|
|
470
1108
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
1109
|
+
WritableMap coordinate = new WritableNativeMap();
|
|
1110
|
+
coordinate.putDouble("latitude", point.latitude);
|
|
1111
|
+
coordinate.putDouble("longitude", point.longitude);
|
|
1112
|
+
event.putMap("coordinate", coordinate);
|
|
1113
|
+
|
|
1114
|
+
Projection projection = map.getProjection();
|
|
1115
|
+
Point screenPoint = projection.toScreenLocation(point);
|
|
477
1116
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
1117
|
+
WritableMap position = new WritableNativeMap();
|
|
1118
|
+
position.putDouble("x", screenPoint.x);
|
|
1119
|
+
position.putDouble("y", screenPoint.y);
|
|
1120
|
+
event.putMap("position", position);
|
|
1121
|
+
|
|
1122
|
+
return event;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
public void updateExtraData(Object extraData) {
|
|
1126
|
+
if (setPaddingDeferred && super.getHeight() > 0 && super.getWidth() > 0) {
|
|
1127
|
+
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
|
|
1128
|
+
|
|
1129
|
+
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1130
|
+
edgeTopPadding + baseTopMapPadding,
|
|
1131
|
+
edgeRightPadding + baseRightMapPadding,
|
|
1132
|
+
edgeBottomPadding + baseBottomMapPadding);
|
|
1133
|
+
map.moveCamera(cu);
|
|
485
1134
|
|
|
486
|
-
|
|
487
|
-
|
|
1135
|
+
// Move the google logo to the default base padding value.
|
|
1136
|
+
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
488
1137
|
|
|
489
|
-
|
|
490
|
-
// todo: use Fabric events
|
|
491
|
-
// eventDispatcher.dispatchEvent(event);
|
|
1138
|
+
setPaddingDeferred = false;
|
|
492
1139
|
}
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
1140
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
@Override
|
|
529
|
-
public void onHostPause() {
|
|
530
|
-
if (hasPermissions() && map != null) {
|
|
531
|
-
//noinspection MissingPermission
|
|
532
|
-
map.setMyLocationEnabled(false);
|
|
533
|
-
}
|
|
534
|
-
synchronized (MapView.this) {
|
|
535
|
-
if (!destroyed) {
|
|
536
|
-
MapView.this.onPause();
|
|
537
|
-
}
|
|
538
|
-
paused = true;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
@Override
|
|
543
|
-
public void onHostDestroy() {
|
|
544
|
-
MapView.this.doDestroy();
|
|
545
|
-
}
|
|
546
|
-
};
|
|
1141
|
+
// if boundsToMove is not null, we now have the MapView's width/height, so we can apply
|
|
1142
|
+
// a proper camera move
|
|
1143
|
+
if (boundsToMove != null) {
|
|
1144
|
+
HashMap<String, Float> data = (HashMap<String, Float>) extraData;
|
|
1145
|
+
int width = data.get("width") == null ? 0 : data.get("width").intValue();
|
|
1146
|
+
int height = data.get("height") == null ? 0 : data.get("height").intValue();
|
|
1147
|
+
|
|
1148
|
+
//fix for https://github.com/react-native-maps/react-native-maps/issues/245,
|
|
1149
|
+
//it's not guaranteed the passed-in height and width would be greater than 0.
|
|
1150
|
+
if (width <= 0 || height <= 0) {
|
|
1151
|
+
map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, 0));
|
|
1152
|
+
} else {
|
|
1153
|
+
map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, width, height, 0));
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
boundsToMove = null;
|
|
1157
|
+
cameraToSet = null;
|
|
1158
|
+
} else if (cameraToSet != null) {
|
|
1159
|
+
map.moveCamera(cameraToSet);
|
|
1160
|
+
cameraToSet = null;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
public void animateToCamera(CameraPosition position, int duration) {
|
|
1164
|
+
if (map == null) return;
|
|
1165
|
+
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
|
|
1166
|
+
if (duration <= 0) {
|
|
1167
|
+
map.moveCamera(update);
|
|
1168
|
+
} else {
|
|
1169
|
+
map.animateCamera(update, duration, null);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
547
1172
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
event = makeClickEventData(selectedMarker.getPosition());
|
|
566
|
-
event.putString("action", "marker-deselect");
|
|
567
|
-
event.putString("id", selectedMarker.getIdentifier());
|
|
568
|
-
dispatchEvent(event, OnMarkerDeselectEvent::new);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
if (target != null) {
|
|
572
|
-
event = makeClickEventData(target.getPosition());
|
|
573
|
-
event.putString("action", "marker-select");
|
|
574
|
-
event.putString("id", target.getIdentifier());
|
|
575
|
-
// todo: use Fabric events
|
|
576
|
-
// manager.pushEvent(context, target, "onSelect", event);
|
|
577
|
-
|
|
578
|
-
event = makeClickEventData(target.getPosition());
|
|
579
|
-
event.putString("action", "marker-select");
|
|
580
|
-
event.putString("id", target.getIdentifier());
|
|
581
|
-
dispatchEvent(event, OnMarkerSelectEvent::new);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
selectedMarker = target;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
private boolean hasPermissions() {
|
|
588
|
-
return checkSelfPermission(getContext(), PERMISSIONS[0]) == PermissionChecker.PERMISSION_GRANTED ||
|
|
589
|
-
checkSelfPermission(getContext(), PERMISSIONS[1]) == PermissionChecker.PERMISSION_GRANTED;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
public static Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
|
|
594
|
-
MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
|
|
595
|
-
builder.put(OnMarkerPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerPressEvent.EVENT_NAME));
|
|
596
|
-
builder.put(OnPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPressEvent.EVENT_NAME));
|
|
597
|
-
builder.put(OnMarkerSelectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerSelectEvent.EVENT_NAME));
|
|
598
|
-
builder.put(OnMarkerDeselectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDeselectEvent.EVENT_NAME));
|
|
599
|
-
builder.put(OnMarkerDragEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEvent.EVENT_NAME));
|
|
600
|
-
builder.put(OnMarkerDragStartEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragStartEvent.EVENT_NAME));
|
|
601
|
-
builder.put(OnMarkerDragEndEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEndEvent.EVENT_NAME));
|
|
602
|
-
builder.put(OnPoiClickEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPoiClickEvent.EVENT_NAME));
|
|
603
|
-
builder.put(OnLongPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnLongPressEvent.EVENT_NAME));
|
|
604
|
-
return builder.build();
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
public static Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
608
|
-
return MapBuilder.of(
|
|
609
|
-
OnMapReadyEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMapReadyEvent.EVENT_NAME),
|
|
610
|
-
OnUserLocationChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnUserLocationChangeEvent.EVENT_NAME),
|
|
611
|
-
OnRegionChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnRegionChangeEvent.EVENT_NAME)
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
/*
|
|
617
|
-
onDestroy is final method so I can't override it.
|
|
618
|
-
*/
|
|
619
|
-
public synchronized void doDestroy() {
|
|
620
|
-
if (destroyed) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
destroyed = true;
|
|
624
|
-
|
|
625
|
-
if (lifecycleListener != null && context != null) {
|
|
626
|
-
context.removeLifecycleEventListener(lifecycleListener);
|
|
627
|
-
lifecycleListener = null;
|
|
628
|
-
}
|
|
629
|
-
if (!paused) {
|
|
630
|
-
onPause();
|
|
631
|
-
paused = true;
|
|
632
|
-
}
|
|
633
|
-
onDestroy();
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
public void setInitialCameraSet(boolean initialCameraSet){
|
|
637
|
-
this.initialCameraSet = initialCameraSet;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
public void setInitialRegion(ReadableMap initialRegion) {
|
|
641
|
-
this.initialRegion = initialRegion;
|
|
642
|
-
// Theoretically onMapReady might be called before setInitialRegion
|
|
643
|
-
// In that case, trigger moveToRegion manually
|
|
644
|
-
if (!initialRegionSet && map != null) {
|
|
645
|
-
moveToRegion(initialRegion);
|
|
646
|
-
initialRegionSet = true;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
public void setInitialCamera(ReadableMap initialCamera) {
|
|
651
|
-
this.initialCamera = initialCamera;
|
|
652
|
-
if (!initialCameraSet && map != null) {
|
|
653
|
-
moveToCamera(initialCamera);
|
|
654
|
-
initialCameraSet = true;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
private void applyBridgedProps() {
|
|
659
|
-
if(initialRegion != null) {
|
|
660
|
-
moveToRegion(initialRegion);
|
|
661
|
-
initialRegionSet = true;
|
|
662
|
-
} else if(region != null) {
|
|
663
|
-
moveToRegion(region);
|
|
664
|
-
} else if (initialCamera != null) {
|
|
665
|
-
moveToCamera(initialCamera);
|
|
666
|
-
initialCameraSet = true;
|
|
667
|
-
} else if (camera != null) {
|
|
668
|
-
moveToCamera(camera);
|
|
669
|
-
}
|
|
670
|
-
if(customMapStyleString != null) {
|
|
671
|
-
map.setMapStyle(new MapStyleOptions(customMapStyleString));
|
|
672
|
-
}
|
|
673
|
-
this.setPoiClickEnabled(poiClickEnabled);
|
|
674
|
-
}
|
|
675
|
-
public static LatLngBounds latLngBoundsFromRegion(ReadableMap region){
|
|
676
|
-
if (region == null) return null;
|
|
677
|
-
|
|
678
|
-
double lng = region.getDouble("longitude");
|
|
679
|
-
double lat = region.getDouble("latitude");
|
|
680
|
-
double lngDelta = region.getDouble("longitudeDelta");
|
|
681
|
-
double latDelta = region.getDouble("latitudeDelta");
|
|
682
|
-
return new LatLngBounds(
|
|
683
|
-
new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest
|
|
684
|
-
new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast
|
|
685
|
-
);
|
|
686
|
-
}
|
|
687
|
-
private void moveToRegion(ReadableMap region) {
|
|
688
|
-
LatLngBounds bounds = latLngBoundsFromRegion(region);
|
|
689
|
-
if (bounds == null) return;
|
|
690
|
-
double lng = region.getDouble("longitude");
|
|
691
|
-
double lat = region.getDouble("latitude");
|
|
692
|
-
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
693
|
-
// in this case, our map has not been laid out yet, so we save the bounds in a local
|
|
694
|
-
// variable, and make a guess of zoomLevel 10. Not to worry, though: as soon as layout
|
|
695
|
-
// occurs, we will move the camera to the saved bounds. Note that if we tried to move
|
|
696
|
-
// to the bounds now, it would trigger an exception.
|
|
697
|
-
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10));
|
|
698
|
-
boundsToMove = bounds;
|
|
699
|
-
} else {
|
|
700
|
-
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
|
|
701
|
-
boundsToMove = null;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
public void setRegion(ReadableMap region) {
|
|
706
|
-
this.region = region;
|
|
707
|
-
if(region != null && map != null) {
|
|
708
|
-
moveToRegion(region);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
public void setCamera(ReadableMap camera) {
|
|
713
|
-
this.camera = camera;
|
|
714
|
-
if(camera != null && map != null) {
|
|
715
|
-
moveToCamera(camera);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
public static CameraPosition cameraPositionFromMap(ReadableMap camera){
|
|
719
|
-
if (camera == null) return null;
|
|
720
|
-
|
|
721
|
-
CameraPosition.Builder builder = new CameraPosition.Builder();
|
|
722
|
-
|
|
723
|
-
ReadableMap center = camera.getMap("center");
|
|
724
|
-
if (center != null) {
|
|
725
|
-
double lng = center.getDouble("longitude");
|
|
726
|
-
double lat = center.getDouble("latitude");
|
|
727
|
-
builder.target(new LatLng(lat, lng));
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
builder.tilt((float)camera.getDouble("pitch"));
|
|
731
|
-
builder.bearing((float)camera.getDouble("heading"));
|
|
732
|
-
builder.zoom((float)camera.getDouble("zoom"));
|
|
733
|
-
|
|
734
|
-
return builder.build();
|
|
735
|
-
}
|
|
736
|
-
public void moveToCamera(ReadableMap cameraMap) {
|
|
737
|
-
CameraPosition camera = cameraPositionFromMap(cameraMap);
|
|
738
|
-
if (camera == null) return;
|
|
739
|
-
CameraUpdate update = CameraUpdateFactory.newCameraPosition(camera);
|
|
740
|
-
|
|
741
|
-
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
742
|
-
// in this case, our map has not been laid out yet, so we save the camera update in a
|
|
743
|
-
// local variable. As soon as layout occurs, we will move the camera to the saved update.
|
|
744
|
-
// Note that if we tried to move to the camera now, it would trigger an exception.
|
|
745
|
-
cameraToSet = update;
|
|
746
|
-
} else {
|
|
747
|
-
map.moveCamera(update);
|
|
748
|
-
cameraToSet = null;
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
public void setMapStyle(@Nullable String customMapStyleString) {
|
|
753
|
-
this.customMapStyleString = customMapStyleString;
|
|
754
|
-
if(map != null && customMapStyleString != null) {
|
|
755
|
-
map.setMapStyle(new MapStyleOptions(customMapStyleString));
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
public void setShowsUserLocation(boolean showUserLocation) {
|
|
760
|
-
this.showUserLocation = showUserLocation; // hold onto this for lifecycle handling
|
|
761
|
-
if (hasPermissions()) {
|
|
762
|
-
map.setLocationSource(fusedLocationSource);
|
|
763
|
-
//noinspection MissingPermission
|
|
764
|
-
map.setMyLocationEnabled(showUserLocation);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
public void setUserLocationPriority(int priority){
|
|
769
|
-
fusedLocationSource.setPriority(priority);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
public void setUserLocationUpdateInterval(int interval){
|
|
773
|
-
fusedLocationSource.setInterval(interval);
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
public void setUserLocationFastestInterval(int interval){
|
|
777
|
-
fusedLocationSource.setFastestInterval(interval);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
public void setShowsMyLocationButton(boolean showMyLocationButton) {
|
|
781
|
-
if (map != null) {
|
|
782
|
-
if (hasPermissions() || !showMyLocationButton) {
|
|
783
|
-
map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
public void setToolbarEnabled(boolean toolbarEnabled) {
|
|
789
|
-
if (map != null) {
|
|
790
|
-
if (hasPermissions() || !toolbarEnabled) {
|
|
791
|
-
map.getUiSettings().setMapToolbarEnabled(toolbarEnabled);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
public void setMapType(int mapType){
|
|
796
|
-
if (map != null) {
|
|
797
|
-
map.setMapType(mapType);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
public void setCacheEnabled(boolean cacheEnabled) {
|
|
802
|
-
this.cacheEnabled = cacheEnabled;
|
|
803
|
-
this.cacheView();
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
public void setPoiClickEnabled(boolean poiClickEnabled) {
|
|
807
|
-
this.poiClickEnabled = poiClickEnabled;
|
|
808
|
-
if (map != null) {
|
|
809
|
-
map.setOnPoiClickListener(poiClickEnabled ? this : null);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
public void setLoadingEnabled(boolean loadingEnabled) {
|
|
814
|
-
if (loadingEnabled && !this.isMapLoaded) {
|
|
815
|
-
this.getMapLoadingLayoutView().setVisibility(View.VISIBLE);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
public void setMoveOnMarkerPress(boolean moveOnPress) {
|
|
820
|
-
this.moveOnMarkerPress = moveOnPress;
|
|
821
|
-
}
|
|
822
|
-
public void setMaxZoomLevel(float maxZoomLevel){
|
|
823
|
-
this.maxZoomLevel = maxZoomLevel;
|
|
824
|
-
if (map != null) {
|
|
825
|
-
map.setMaxZoomPreference(maxZoomLevel);
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
public void setMinZoomLevel(float minZoomLevel){
|
|
829
|
-
this.minZoomLevel = minZoomLevel;
|
|
830
|
-
if (map != null) {
|
|
831
|
-
map.setMinZoomPreference(minZoomLevel);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
public void setPitchEnabled(boolean pitchEnabled){
|
|
835
|
-
this.pitchEnabled = pitchEnabled;
|
|
836
|
-
if (map != null) {
|
|
837
|
-
map.getUiSettings().setTiltGesturesEnabled(pitchEnabled);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
public void setShowsCompass(boolean showsCompass){
|
|
841
|
-
this.showsCompass = showsCompass;
|
|
842
|
-
if (map != null) {
|
|
843
|
-
map.getUiSettings().setCompassEnabled(showsCompass);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
public void setRotateEnabled(boolean rotateEnabled){
|
|
847
|
-
this.rotateEnabled = rotateEnabled;
|
|
848
|
-
if (map != null) {
|
|
849
|
-
map.getUiSettings().setRotateGesturesEnabled(rotateEnabled);
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
public void setZoomEnabled(boolean zoomEnabled){
|
|
853
|
-
this.zoomEnabled = zoomEnabled;
|
|
854
|
-
if (map != null) {
|
|
855
|
-
map.getUiSettings().setZoomGesturesEnabled(zoomEnabled);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
public void setZoomControlEnabled(boolean zoomControlEnabled){
|
|
859
|
-
this.zoomControlEnabled = zoomControlEnabled;
|
|
860
|
-
if (map != null) {
|
|
861
|
-
map.getUiSettings().setZoomControlsEnabled(zoomControlEnabled);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
public void setScrollDuringRotateOrZoomEnabled(boolean scrollDuringRotateOrZoomEnabled){
|
|
865
|
-
this.scrollDuringRotateOrZoomEnabled = scrollDuringRotateOrZoomEnabled;
|
|
866
|
-
if (map != null) {
|
|
867
|
-
map.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringRotateOrZoomEnabled);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
public void setScrollEnabled(boolean scrollEnabled){
|
|
871
|
-
this.scrollEnabled = scrollEnabled;
|
|
872
|
-
if (map != null) {
|
|
873
|
-
map.getUiSettings().setScrollGesturesEnabled(scrollEnabled);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
public void setShowIndoors(boolean showIndoors){
|
|
877
|
-
this.showIndoors = showIndoors;
|
|
878
|
-
if (map != null) {
|
|
879
|
-
map.setIndoorEnabled(showIndoors);
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
public void setShowsIndoorLevelPicker(boolean showsIndoorLevelPicker) {
|
|
883
|
-
this.showsIndoorLevelPicker = showsIndoorLevelPicker;
|
|
884
|
-
if (map != null) {
|
|
885
|
-
map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
public void setShowBuildings(boolean showBuildings) {
|
|
889
|
-
this.setShowBuildings = showBuildings;
|
|
890
|
-
if (map != null) {
|
|
891
|
-
map.setBuildingsEnabled(showBuildings);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
public void setLoadingBackgroundColor(Integer loadingBackgroundColor) {
|
|
897
|
-
this.loadingBackgroundColor = loadingBackgroundColor;
|
|
898
|
-
|
|
899
|
-
if (this.mapLoadingLayout != null) {
|
|
900
|
-
if (loadingBackgroundColor == null) {
|
|
901
|
-
this.mapLoadingLayout.setBackgroundColor(Color.WHITE);
|
|
902
|
-
} else {
|
|
903
|
-
this.mapLoadingLayout.setBackgroundColor(this.loadingBackgroundColor);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
public void setLoadingIndicatorColor(Integer loadingIndicatorColor) {
|
|
909
|
-
this.loadingIndicatorColor = loadingIndicatorColor;
|
|
910
|
-
if (this.mapLoadingProgressBar != null) {
|
|
911
|
-
Integer color = loadingIndicatorColor;
|
|
912
|
-
if (color == null) {
|
|
913
|
-
color = Color.parseColor("#606060");
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
ColorStateList progressTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
917
|
-
ColorStateList secondaryProgressTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
918
|
-
ColorStateList indeterminateTintList = ColorStateList.valueOf(loadingIndicatorColor);
|
|
919
|
-
|
|
920
|
-
this.mapLoadingProgressBar.setProgressTintList(progressTintList);
|
|
921
|
-
this.mapLoadingProgressBar.setSecondaryProgressTintList(secondaryProgressTintList);
|
|
922
|
-
this.mapLoadingProgressBar.setIndeterminateTintList(indeterminateTintList);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
public void setHandlePanDrag(boolean handlePanDrag) {
|
|
927
|
-
this.handlePanDrag = handlePanDrag;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
public void addFeature(View child, int index) {
|
|
931
|
-
// Our desired API is to pass up annotations/overlays as children to the mapview component.
|
|
932
|
-
// This is where we intercept them and do the appropriate underlying mapview action.
|
|
933
|
-
if (child instanceof MapMarker) {
|
|
934
|
-
MapMarker annotation = (MapMarker) child;
|
|
935
|
-
annotation.addToMap(markerCollection);
|
|
936
|
-
features.add(index, annotation);
|
|
937
|
-
|
|
938
|
-
// Allow visibility event to be triggered later
|
|
939
|
-
int visibility = annotation.getVisibility();
|
|
940
|
-
annotation.setVisibility(INVISIBLE);
|
|
941
|
-
|
|
942
|
-
// Remove from a view group if already present, prevent "specified child
|
|
943
|
-
// already had a parent" error.
|
|
944
|
-
ViewGroup annotationParent = (ViewGroup)annotation.getParent();
|
|
945
|
-
if (annotationParent != null) {
|
|
946
|
-
annotationParent.removeView(annotation);
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
// Add to the parent group
|
|
950
|
-
attacherGroup.addView(annotation);
|
|
951
|
-
|
|
952
|
-
// Trigger visibility event if necessary.
|
|
953
|
-
// With some testing, seems like it is not always
|
|
954
|
-
// triggered just by being added to a parent view.
|
|
955
|
-
annotation.setVisibility(visibility);
|
|
956
|
-
|
|
957
|
-
Marker marker = (Marker) annotation.getFeature();
|
|
958
|
-
markerMap.put(marker, annotation);
|
|
959
|
-
} else if (child instanceof MapPolyline) {
|
|
960
|
-
MapPolyline polylineView = (MapPolyline) child;
|
|
961
|
-
polylineView.addToMap(polylineCollection);
|
|
962
|
-
features.add(index, polylineView);
|
|
963
|
-
Polyline polyline = (Polyline) polylineView.getFeature();
|
|
964
|
-
polylineMap.put(polyline, polylineView);
|
|
965
|
-
} else if (child instanceof MapGradientPolyline) {
|
|
966
|
-
MapGradientPolyline polylineView = (MapGradientPolyline) child;
|
|
967
|
-
polylineView.addToMap(map);
|
|
968
|
-
features.add(index, polylineView);
|
|
969
|
-
TileOverlay tileOverlay = (TileOverlay) polylineView.getFeature();
|
|
970
|
-
gradientPolylineMap.put(tileOverlay, polylineView);
|
|
971
|
-
} else if (child instanceof MapPolygon) {
|
|
972
|
-
MapPolygon polygonView = (MapPolygon) child;
|
|
973
|
-
polygonView.addToMap(polygonCollection);
|
|
974
|
-
features.add(index, polygonView);
|
|
975
|
-
Polygon polygon = (Polygon) polygonView.getFeature();
|
|
976
|
-
polygonMap.put(polygon, polygonView);
|
|
977
|
-
} else if (child instanceof MapCircle) {
|
|
978
|
-
MapCircle circleView = (MapCircle) child;
|
|
979
|
-
circleView.addToMap(circleCollection);
|
|
980
|
-
features.add(index, circleView);
|
|
981
|
-
} else if (child instanceof MapUrlTile) {
|
|
982
|
-
MapUrlTile urlTileView = (MapUrlTile) child;
|
|
983
|
-
urlTileView.addToMap(map);
|
|
984
|
-
features.add(index, urlTileView);
|
|
985
|
-
} else if (child instanceof MapWMSTile) {
|
|
986
|
-
MapWMSTile urlTileView = (MapWMSTile) child;
|
|
987
|
-
urlTileView.addToMap(map);
|
|
988
|
-
features.add(index, urlTileView);
|
|
989
|
-
} else if (child instanceof MapLocalTile) {
|
|
990
|
-
MapLocalTile localTileView = (MapLocalTile) child;
|
|
991
|
-
localTileView.addToMap(map);
|
|
992
|
-
features.add(index, localTileView);
|
|
993
|
-
} else if (child instanceof MapOverlay) {
|
|
994
|
-
MapOverlay overlayView = (MapOverlay) child;
|
|
995
|
-
overlayView.addToMap(groundOverlayCollection);
|
|
996
|
-
features.add(index, overlayView);
|
|
997
|
-
GroundOverlay overlay = (GroundOverlay) overlayView.getFeature();
|
|
998
|
-
overlayMap.put(overlay, overlayView);
|
|
999
|
-
} else if (child instanceof MapHeatmap) {
|
|
1000
|
-
MapHeatmap heatmapView = (MapHeatmap) child;
|
|
1001
|
-
heatmapView.addToMap(map);
|
|
1002
|
-
features.add(index, heatmapView);
|
|
1003
|
-
TileOverlay heatmap = (TileOverlay)heatmapView.getFeature();
|
|
1004
|
-
heatmapMap.put(heatmap, heatmapView);
|
|
1005
|
-
} else if (child instanceof ViewGroup) {
|
|
1006
|
-
ViewGroup children = (ViewGroup) child;
|
|
1007
|
-
for (int i = 0; i < children.getChildCount(); i++) {
|
|
1008
|
-
addFeature(children.getChildAt(i), index);
|
|
1009
|
-
}
|
|
1010
|
-
} else {
|
|
1011
|
-
addView(child, index);
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
public int getFeatureCount() {
|
|
1016
|
-
return features.size();
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
public View getFeatureAt(int index) {
|
|
1020
|
-
return features.get(index);
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
public void removeFeatureAt(int index) {
|
|
1024
|
-
MapFeature feature = features.remove(index);
|
|
1025
|
-
if (feature instanceof MapMarker) {
|
|
1026
|
-
markerMap.remove(feature.getFeature());
|
|
1027
|
-
feature.removeFromMap(markerCollection);
|
|
1028
|
-
attacherGroup.removeView(feature);
|
|
1029
|
-
} else if (feature instanceof MapHeatmap) {
|
|
1030
|
-
heatmapMap.remove(feature.getFeature());
|
|
1031
|
-
feature.removeFromMap(map);
|
|
1032
|
-
} else if(feature instanceof MapCircle) {
|
|
1033
|
-
feature.removeFromMap(circleCollection);
|
|
1034
|
-
} else if(feature instanceof MapOverlay) {
|
|
1035
|
-
feature.removeFromMap(groundOverlayCollection);
|
|
1036
|
-
} else if(feature instanceof MapPolygon) {
|
|
1037
|
-
feature.removeFromMap(polygonCollection);
|
|
1038
|
-
} else if(feature instanceof MapPolyline) {
|
|
1039
|
-
feature.removeFromMap(polylineCollection);
|
|
1040
|
-
} else {
|
|
1041
|
-
feature.removeFromMap(map);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
public WritableMap makeClickEventData(LatLng point) {
|
|
1046
|
-
WritableMap event = new WritableNativeMap();
|
|
1047
|
-
|
|
1048
|
-
WritableMap coordinate = new WritableNativeMap();
|
|
1049
|
-
coordinate.putDouble("latitude", point.latitude);
|
|
1050
|
-
coordinate.putDouble("longitude", point.longitude);
|
|
1051
|
-
event.putMap("coordinate", coordinate);
|
|
1052
|
-
|
|
1053
|
-
Projection projection = map.getProjection();
|
|
1054
|
-
Point screenPoint = projection.toScreenLocation(point);
|
|
1055
|
-
|
|
1056
|
-
WritableMap position = new WritableNativeMap();
|
|
1057
|
-
position.putDouble("x", screenPoint.x);
|
|
1058
|
-
position.putDouble("y", screenPoint.y);
|
|
1059
|
-
event.putMap("position", position);
|
|
1060
|
-
|
|
1061
|
-
return event;
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
public void updateExtraData(Object extraData) {
|
|
1065
|
-
if (setPaddingDeferred && super.getHeight() > 0 && super.getWidth() > 0) {
|
|
1066
|
-
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
|
|
1067
|
-
|
|
1068
|
-
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1069
|
-
edgeTopPadding + baseTopMapPadding,
|
|
1070
|
-
edgeRightPadding + baseRightMapPadding,
|
|
1071
|
-
edgeBottomPadding + baseBottomMapPadding);
|
|
1072
|
-
map.moveCamera(cu);
|
|
1073
|
-
|
|
1074
|
-
// Move the google logo to the default base padding value.
|
|
1075
|
-
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1076
|
-
|
|
1077
|
-
setPaddingDeferred = false;
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
// if boundsToMove is not null, we now have the MapView's width/height, so we can apply
|
|
1081
|
-
// a proper camera move
|
|
1082
|
-
if (boundsToMove != null) {
|
|
1083
|
-
HashMap<String, Float> data = (HashMap<String, Float>) extraData;
|
|
1084
|
-
int width = data.get("width") == null ? 0 : data.get("width").intValue();
|
|
1085
|
-
int height = data.get("height") == null ? 0 : data.get("height").intValue();
|
|
1086
|
-
|
|
1087
|
-
//fix for https://github.com/react-native-maps/react-native-maps/issues/245,
|
|
1088
|
-
//it's not guaranteed the passed-in height and width would be greater than 0.
|
|
1089
|
-
if (width <= 0 || height <= 0) {
|
|
1090
|
-
map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, 0));
|
|
1091
|
-
} else {
|
|
1092
|
-
map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, width, height, 0));
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
boundsToMove = null;
|
|
1096
|
-
cameraToSet = null;
|
|
1097
|
-
}
|
|
1098
|
-
else if (cameraToSet != null) {
|
|
1099
|
-
map.moveCamera(cameraToSet);
|
|
1100
|
-
cameraToSet = null;
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
public void animateToCamera(ReadableMap camera, int duration) {
|
|
1105
|
-
if (map == null) return;
|
|
1106
|
-
CameraPosition.Builder builder = new CameraPosition.Builder(map.getCameraPosition());
|
|
1107
|
-
if (camera.hasKey("zoom")) {
|
|
1108
|
-
builder.zoom((float)camera.getDouble("zoom"));
|
|
1109
|
-
}
|
|
1110
|
-
if (camera.hasKey("heading")) {
|
|
1111
|
-
builder.bearing((float)camera.getDouble("heading"));
|
|
1173
|
+
public void animateToCamera(ReadableMap camera, int duration) {
|
|
1174
|
+
if (map == null) return;
|
|
1175
|
+
CameraPosition.Builder builder = new CameraPosition.Builder(map.getCameraPosition());
|
|
1176
|
+
if (camera.hasKey("zoom")) {
|
|
1177
|
+
builder.zoom((float) camera.getDouble("zoom"));
|
|
1178
|
+
}
|
|
1179
|
+
if (camera.hasKey("heading")) {
|
|
1180
|
+
builder.bearing((float) camera.getDouble("heading"));
|
|
1181
|
+
}
|
|
1182
|
+
if (camera.hasKey("pitch")) {
|
|
1183
|
+
builder.tilt((float) camera.getDouble("pitch"));
|
|
1184
|
+
}
|
|
1185
|
+
if (camera.hasKey("center")) {
|
|
1186
|
+
ReadableMap center = camera.getMap("center");
|
|
1187
|
+
builder.target(new LatLng(center.getDouble("latitude"), center.getDouble("longitude")));
|
|
1188
|
+
}
|
|
1189
|
+
animateToCamera(builder.build(), duration);
|
|
1112
1190
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
CameraUpdate update = CameraUpdateFactory.newCameraPosition(builder.build());
|
|
1122
|
-
|
|
1123
|
-
if (duration <= 0) {
|
|
1124
|
-
map.moveCamera(update);
|
|
1125
|
-
}
|
|
1126
|
-
else {
|
|
1127
|
-
map.animateCamera(update, duration, null);
|
|
1191
|
+
|
|
1192
|
+
public void animateToRegion(LatLngBounds bounds, int duration) {
|
|
1193
|
+
if (map == null) return;
|
|
1194
|
+
if (duration <= 0) {
|
|
1195
|
+
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
|
|
1196
|
+
} else {
|
|
1197
|
+
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null);
|
|
1198
|
+
}
|
|
1128
1199
|
}
|
|
1129
|
-
}
|
|
1130
1200
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1201
|
+
public void fitToElements(ReadableMap edgePadding, boolean animated) {
|
|
1202
|
+
if (map == null) return;
|
|
1203
|
+
|
|
1204
|
+
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1205
|
+
|
|
1206
|
+
boolean addedPosition = false;
|
|
1207
|
+
|
|
1208
|
+
for (MapFeature feature : features) {
|
|
1209
|
+
if (feature instanceof MapMarker) {
|
|
1210
|
+
Marker marker = (Marker) feature.getFeature();
|
|
1211
|
+
builder.include(marker.getPosition());
|
|
1212
|
+
addedPosition = true;
|
|
1213
|
+
}
|
|
1214
|
+
// TODO(lmr): may want to include shapes / etc.
|
|
1215
|
+
}
|
|
1216
|
+
if (addedPosition) {
|
|
1217
|
+
LatLngBounds bounds = builder.build();
|
|
1218
|
+
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
|
|
1219
|
+
|
|
1220
|
+
if (edgePadding != null) {
|
|
1221
|
+
appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
|
|
1222
|
+
edgePadding.getInt("right"), edgePadding.getInt("bottom"));
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
if (animated) {
|
|
1226
|
+
map.animateCamera(cu);
|
|
1227
|
+
} else {
|
|
1228
|
+
map.moveCamera(cu);
|
|
1229
|
+
}
|
|
1230
|
+
// Move the google logo to the default base padding value.
|
|
1231
|
+
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1232
|
+
}
|
|
1137
1233
|
}
|
|
1138
|
-
}
|
|
1139
1234
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1235
|
+
public void fitToSuppliedMarkers(ReadableArray markerIDsArray, ReadableMap edgePadding, boolean animated) {
|
|
1236
|
+
if (map == null) return;
|
|
1237
|
+
|
|
1238
|
+
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1239
|
+
|
|
1240
|
+
String[] markerIDs = new String[markerIDsArray.size()];
|
|
1241
|
+
for (int i = 0; i < markerIDsArray.size(); i++) {
|
|
1242
|
+
markerIDs[i] = markerIDsArray.getString(i);
|
|
1243
|
+
}
|
|
1142
1244
|
|
|
1143
|
-
|
|
1245
|
+
boolean addedPosition = false;
|
|
1144
1246
|
|
|
1145
|
-
|
|
1247
|
+
List<String> markerIDList = Arrays.asList(markerIDs);
|
|
1146
1248
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1249
|
+
for (MapFeature feature : features) {
|
|
1250
|
+
if (feature instanceof MapMarker) {
|
|
1251
|
+
String identifier = ((MapMarker) feature).getIdentifier();
|
|
1252
|
+
Marker marker = (Marker) feature.getFeature();
|
|
1253
|
+
if (markerIDList.contains(identifier)) {
|
|
1254
|
+
builder.include(marker.getPosition());
|
|
1255
|
+
addedPosition = true;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
if (addedPosition) {
|
|
1261
|
+
LatLngBounds bounds = builder.build();
|
|
1262
|
+
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
|
|
1263
|
+
|
|
1264
|
+
if (edgePadding != null) {
|
|
1265
|
+
appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
|
|
1266
|
+
edgePadding.getInt("right"), edgePadding.getInt("bottom"));
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
if (animated) {
|
|
1270
|
+
map.animateCamera(cu);
|
|
1271
|
+
} else {
|
|
1272
|
+
map.moveCamera(cu);
|
|
1273
|
+
}
|
|
1274
|
+
// Move the google logo to the default base padding value.
|
|
1275
|
+
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1276
|
+
}
|
|
1154
1277
|
}
|
|
1155
|
-
if (addedPosition) {
|
|
1156
|
-
LatLngBounds bounds = builder.build();
|
|
1157
|
-
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
|
|
1158
1278
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1279
|
+
// padding configured by 'mapPadding' property
|
|
1280
|
+
int baseLeftMapPadding;
|
|
1281
|
+
int baseRightMapPadding;
|
|
1282
|
+
int baseTopMapPadding;
|
|
1283
|
+
int baseBottomMapPadding;
|
|
1284
|
+
// extra padding specified by 'edgePadding' option of fitToElements/fitToSuppliedMarkers/fitToCoordinates
|
|
1285
|
+
int edgeLeftPadding;
|
|
1286
|
+
int edgeRightPadding;
|
|
1287
|
+
int edgeTopPadding;
|
|
1288
|
+
int edgeBottomPadding;
|
|
1289
|
+
|
|
1290
|
+
public void applyBaseMapPadding(int left, int top, int right, int bottom) {
|
|
1291
|
+
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
1292
|
+
// the map is not laid out yet and calling setPadding() now has no effect
|
|
1293
|
+
baseLeftMapPadding = left;
|
|
1294
|
+
baseRightMapPadding = right;
|
|
1295
|
+
baseTopMapPadding = top;
|
|
1296
|
+
baseBottomMapPadding = bottom;
|
|
1297
|
+
setPaddingDeferred = true;
|
|
1298
|
+
return;
|
|
1299
|
+
}
|
|
1163
1300
|
|
|
1164
|
-
|
|
1165
|
-
map.
|
|
1166
|
-
|
|
1301
|
+
// retrieve current camera with current edge paddings configured
|
|
1302
|
+
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1303
|
+
edgeTopPadding + baseTopMapPadding,
|
|
1304
|
+
edgeRightPadding + baseRightMapPadding,
|
|
1305
|
+
edgeBottomPadding + baseBottomMapPadding);
|
|
1306
|
+
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
|
|
1307
|
+
|
|
1308
|
+
baseLeftMapPadding = left;
|
|
1309
|
+
baseRightMapPadding = right;
|
|
1310
|
+
baseTopMapPadding = top;
|
|
1311
|
+
baseBottomMapPadding = bottom;
|
|
1312
|
+
|
|
1313
|
+
// apply base paddings and restore center position of the map
|
|
1314
|
+
map.setPadding(edgeLeftPadding + left,
|
|
1315
|
+
edgeTopPadding + top,
|
|
1316
|
+
edgeRightPadding + right,
|
|
1317
|
+
edgeBottomPadding + bottom);
|
|
1167
1318
|
map.moveCamera(cu);
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1319
|
+
|
|
1320
|
+
// Move the google logo to the default base padding value.
|
|
1321
|
+
map.setPadding(left, top, right, bottom);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding,
|
|
1325
|
+
boolean animated) {
|
|
1326
|
+
if (map == null) return;
|
|
1327
|
+
|
|
1328
|
+
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1329
|
+
|
|
1330
|
+
for (int i = 0; i < coordinatesArray.size(); i++) {
|
|
1331
|
+
ReadableMap latLng = coordinatesArray.getMap(i);
|
|
1332
|
+
double lat = latLng.getDouble("latitude");
|
|
1333
|
+
double lng = latLng.getDouble("longitude");
|
|
1334
|
+
builder.include(new LatLng(lat, lng));
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
LatLngBounds bounds = builder.build();
|
|
1338
|
+
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
|
|
1339
|
+
|
|
1340
|
+
if (edgePadding != null) {
|
|
1341
|
+
appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), edgePadding.getInt("right"), edgePadding.getInt("bottom"));
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
if (animated) {
|
|
1345
|
+
map.animateCamera(cu);
|
|
1346
|
+
} else {
|
|
1347
|
+
map.moveCamera(cu);
|
|
1348
|
+
}
|
|
1349
|
+
// Move the google logo to the default base padding value.
|
|
1350
|
+
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1171
1351
|
}
|
|
1172
|
-
}
|
|
1173
1352
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1353
|
+
private void appendMapPadding(int iLeft, int iTop, int iRight, int iBottom) {
|
|
1354
|
+
double density = getResources().getDisplayMetrics().density;
|
|
1355
|
+
|
|
1356
|
+
edgeLeftPadding = (int) (iLeft * density);
|
|
1357
|
+
edgeTopPadding = (int) (iTop * density);
|
|
1358
|
+
edgeRightPadding = (int) (iRight * density);
|
|
1359
|
+
edgeBottomPadding = (int) (iBottom * density);
|
|
1360
|
+
|
|
1361
|
+
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1362
|
+
edgeTopPadding + baseTopMapPadding,
|
|
1363
|
+
edgeRightPadding + baseRightMapPadding,
|
|
1364
|
+
edgeBottomPadding + baseBottomMapPadding);
|
|
1365
|
+
}
|
|
1176
1366
|
|
|
1177
|
-
|
|
1367
|
+
public double[][] getMapBoundaries() {
|
|
1368
|
+
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
|
|
1369
|
+
LatLng northEast = bounds.northeast;
|
|
1370
|
+
LatLng southWest = bounds.southwest;
|
|
1178
1371
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1372
|
+
return new double[][]{
|
|
1373
|
+
{northEast.longitude, northEast.latitude},
|
|
1374
|
+
{southWest.longitude, southWest.latitude}
|
|
1375
|
+
};
|
|
1182
1376
|
}
|
|
1183
1377
|
|
|
1184
|
-
|
|
1378
|
+
public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) {
|
|
1379
|
+
if (map == null) return;
|
|
1380
|
+
|
|
1381
|
+
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1185
1382
|
|
|
1186
|
-
|
|
1383
|
+
double latNE = northEast.getDouble("latitude");
|
|
1384
|
+
double lngNE = northEast.getDouble("longitude");
|
|
1385
|
+
builder.include(new LatLng(latNE, lngNE));
|
|
1187
1386
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1387
|
+
double latSW = southWest.getDouble("latitude");
|
|
1388
|
+
double lngSW = southWest.getDouble("longitude");
|
|
1389
|
+
builder.include(new LatLng(latSW, lngSW));
|
|
1390
|
+
|
|
1391
|
+
LatLngBounds bounds = builder.build();
|
|
1392
|
+
|
|
1393
|
+
map.setLatLngBoundsForCameraTarget(bounds);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// InfoWindowAdapter interface
|
|
1397
|
+
|
|
1398
|
+
@Override
|
|
1399
|
+
public View getInfoWindow(Marker marker) {
|
|
1400
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
1401
|
+
return markerView.getCallout();
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
@Override
|
|
1405
|
+
public View getInfoContents(Marker marker) {
|
|
1406
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
1407
|
+
return markerView.getInfoContents();
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
@Override
|
|
1411
|
+
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
1412
|
+
gestureDetector.onTouchEvent(ev);
|
|
1413
|
+
|
|
1414
|
+
int X = (int) ev.getX();
|
|
1415
|
+
int Y = (int) ev.getY();
|
|
1416
|
+
if (map != null) {
|
|
1417
|
+
tapLocation = map.getProjection().fromScreenLocation(new Point(X, Y));
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
int action = MotionEventCompat.getActionMasked(ev);
|
|
1421
|
+
|
|
1422
|
+
switch (action) {
|
|
1423
|
+
case (MotionEvent.ACTION_DOWN):
|
|
1424
|
+
this.getParent().requestDisallowInterceptTouchEvent(
|
|
1425
|
+
map != null && map.getUiSettings().isScrollGesturesEnabled());
|
|
1426
|
+
break;
|
|
1427
|
+
case (MotionEvent.ACTION_UP):
|
|
1428
|
+
// Clear this regardless, since isScrollGesturesEnabled() may have been updated
|
|
1429
|
+
this.getParent().requestDisallowInterceptTouchEvent(false);
|
|
1430
|
+
break;
|
|
1195
1431
|
}
|
|
1196
|
-
|
|
1432
|
+
super.dispatchTouchEvent(ev);
|
|
1433
|
+
return true;
|
|
1197
1434
|
}
|
|
1198
1435
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1436
|
+
@Override
|
|
1437
|
+
public void onMarkerDragStart(Marker marker) {
|
|
1438
|
+
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1439
|
+
// todo: use Fabric events
|
|
1440
|
+
dispatchEvent(event, OnMarkerDragStartEvent::new);
|
|
1202
1441
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1442
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
1443
|
+
event = makeClickEventData(marker.getPosition());
|
|
1444
|
+
// todo: use Fabric events
|
|
1445
|
+
// manager.pushEvent(context, markerView, "onDragStart", event);
|
|
1446
|
+
}
|
|
1207
1447
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
}
|
|
1213
|
-
// Move the google logo to the default base padding value.
|
|
1214
|
-
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
// padding configured by 'mapPadding' property
|
|
1219
|
-
int baseLeftMapPadding;
|
|
1220
|
-
int baseRightMapPadding;
|
|
1221
|
-
int baseTopMapPadding;
|
|
1222
|
-
int baseBottomMapPadding;
|
|
1223
|
-
// extra padding specified by 'edgePadding' option of fitToElements/fitToSuppliedMarkers/fitToCoordinates
|
|
1224
|
-
int edgeLeftPadding;
|
|
1225
|
-
int edgeRightPadding;
|
|
1226
|
-
int edgeTopPadding;
|
|
1227
|
-
int edgeBottomPadding;
|
|
1228
|
-
|
|
1229
|
-
public void applyBaseMapPadding(int left, int top, int right, int bottom){
|
|
1230
|
-
if (super.getHeight() <= 0 || super.getWidth() <= 0) {
|
|
1231
|
-
// the map is not laid out yet and calling setPadding() now has no effect
|
|
1232
|
-
baseLeftMapPadding = left;
|
|
1233
|
-
baseRightMapPadding = right;
|
|
1234
|
-
baseTopMapPadding = top;
|
|
1235
|
-
baseBottomMapPadding = bottom;
|
|
1236
|
-
setPaddingDeferred = true;
|
|
1237
|
-
return;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
// retrieve current camera with current edge paddings configured
|
|
1241
|
-
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1242
|
-
edgeTopPadding + baseTopMapPadding,
|
|
1243
|
-
edgeRightPadding + baseRightMapPadding,
|
|
1244
|
-
edgeBottomPadding + baseBottomMapPadding);
|
|
1245
|
-
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
|
|
1246
|
-
|
|
1247
|
-
baseLeftMapPadding = left;
|
|
1248
|
-
baseRightMapPadding = right;
|
|
1249
|
-
baseTopMapPadding = top;
|
|
1250
|
-
baseBottomMapPadding = bottom;
|
|
1251
|
-
|
|
1252
|
-
// apply base paddings and restore center position of the map
|
|
1253
|
-
map.setPadding(edgeLeftPadding + left,
|
|
1254
|
-
edgeTopPadding + top,
|
|
1255
|
-
edgeRightPadding + right,
|
|
1256
|
-
edgeBottomPadding + bottom);
|
|
1257
|
-
map.moveCamera(cu);
|
|
1258
|
-
|
|
1259
|
-
// Move the google logo to the default base padding value.
|
|
1260
|
-
map.setPadding(left, top, right, bottom);
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding,
|
|
1264
|
-
boolean animated) {
|
|
1265
|
-
if (map == null) return;
|
|
1266
|
-
|
|
1267
|
-
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1268
|
-
|
|
1269
|
-
for (int i = 0; i < coordinatesArray.size(); i++) {
|
|
1270
|
-
ReadableMap latLng = coordinatesArray.getMap(i);
|
|
1271
|
-
double lat = latLng.getDouble("latitude");
|
|
1272
|
-
double lng = latLng.getDouble("longitude");
|
|
1273
|
-
builder.include(new LatLng(lat, lng));
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
LatLngBounds bounds = builder.build();
|
|
1277
|
-
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
|
|
1278
|
-
|
|
1279
|
-
if (edgePadding != null) {
|
|
1280
|
-
appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), edgePadding.getInt("right"), edgePadding.getInt("bottom"));
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
if (animated) {
|
|
1284
|
-
map.animateCamera(cu);
|
|
1285
|
-
} else {
|
|
1286
|
-
map.moveCamera(cu);
|
|
1287
|
-
}
|
|
1288
|
-
// Move the google logo to the default base padding value.
|
|
1289
|
-
map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
private void appendMapPadding(int iLeft,int iTop, int iRight, int iBottom) {
|
|
1293
|
-
double density = getResources().getDisplayMetrics().density;
|
|
1294
|
-
|
|
1295
|
-
edgeLeftPadding = (int) (iLeft * density);
|
|
1296
|
-
edgeTopPadding = (int) (iTop * density);
|
|
1297
|
-
edgeRightPadding = (int) (iRight * density);
|
|
1298
|
-
edgeBottomPadding = (int) (iBottom * density);
|
|
1299
|
-
|
|
1300
|
-
map.setPadding(edgeLeftPadding + baseLeftMapPadding,
|
|
1301
|
-
edgeTopPadding + baseTopMapPadding,
|
|
1302
|
-
edgeRightPadding + baseRightMapPadding,
|
|
1303
|
-
edgeBottomPadding + baseBottomMapPadding);
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
public double[][] getMapBoundaries() {
|
|
1307
|
-
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
|
|
1308
|
-
LatLng northEast = bounds.northeast;
|
|
1309
|
-
LatLng southWest = bounds.southwest;
|
|
1310
|
-
|
|
1311
|
-
return new double[][] {
|
|
1312
|
-
{northEast.longitude, northEast.latitude},
|
|
1313
|
-
{southWest.longitude, southWest.latitude}
|
|
1314
|
-
};
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) {
|
|
1318
|
-
if (map == null) return;
|
|
1319
|
-
|
|
1320
|
-
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
|
1321
|
-
|
|
1322
|
-
double latNE = northEast.getDouble("latitude");
|
|
1323
|
-
double lngNE = northEast.getDouble("longitude");
|
|
1324
|
-
builder.include(new LatLng(latNE, lngNE));
|
|
1325
|
-
|
|
1326
|
-
double latSW = southWest.getDouble("latitude");
|
|
1327
|
-
double lngSW = southWest.getDouble("longitude");
|
|
1328
|
-
builder.include(new LatLng(latSW, lngSW));
|
|
1448
|
+
@Override
|
|
1449
|
+
public void onMarkerDrag(Marker marker) {
|
|
1450
|
+
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1451
|
+
dispatchEvent(event, OnMarkerDragEvent::new);
|
|
1329
1452
|
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
map.setLatLngBoundsForCameraTarget(bounds);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
// InfoWindowAdapter interface
|
|
1336
|
-
|
|
1337
|
-
@Override
|
|
1338
|
-
public View getInfoWindow(Marker marker) {
|
|
1339
|
-
MapMarker markerView = getMarkerMap(marker);
|
|
1340
|
-
return markerView.getCallout();
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
@Override
|
|
1344
|
-
public View getInfoContents(Marker marker) {
|
|
1345
|
-
MapMarker markerView = getMarkerMap(marker);
|
|
1346
|
-
return markerView.getInfoContents();
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
@Override
|
|
1350
|
-
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
1351
|
-
gestureDetector.onTouchEvent(ev);
|
|
1352
|
-
|
|
1353
|
-
int X = (int)ev.getX();
|
|
1354
|
-
int Y = (int)ev.getY();
|
|
1355
|
-
if(map != null) {
|
|
1356
|
-
tapLocation = map.getProjection().fromScreenLocation(new Point(X,Y));
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
int action = MotionEventCompat.getActionMasked(ev);
|
|
1360
|
-
|
|
1361
|
-
switch (action) {
|
|
1362
|
-
case (MotionEvent.ACTION_DOWN):
|
|
1363
|
-
this.getParent().requestDisallowInterceptTouchEvent(
|
|
1364
|
-
map != null && map.getUiSettings().isScrollGesturesEnabled());
|
|
1365
|
-
break;
|
|
1366
|
-
case (MotionEvent.ACTION_UP):
|
|
1367
|
-
// Clear this regardless, since isScrollGesturesEnabled() may have been updated
|
|
1368
|
-
this.getParent().requestDisallowInterceptTouchEvent(false);
|
|
1369
|
-
break;
|
|
1370
|
-
}
|
|
1371
|
-
super.dispatchTouchEvent(ev);
|
|
1372
|
-
return true;
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
@Override
|
|
1376
|
-
public void onMarkerDragStart(Marker marker) {
|
|
1377
|
-
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1378
|
-
// todo: use Fabric events
|
|
1379
|
-
dispatchEvent(event, OnMarkerDragStartEvent::new);
|
|
1380
|
-
|
|
1381
|
-
MapMarker markerView = getMarkerMap(marker);
|
|
1382
|
-
event = makeClickEventData(marker.getPosition());
|
|
1383
|
-
// todo: use Fabric events
|
|
1384
|
-
// manager.pushEvent(context, markerView, "onDragStart", event);
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
@Override
|
|
1388
|
-
public void onMarkerDrag(Marker marker) {
|
|
1389
|
-
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1390
|
-
dispatchEvent(event, OnMarkerDragEvent::new);
|
|
1391
|
-
|
|
1392
|
-
MapMarker markerView = getMarkerMap(marker);
|
|
1393
|
-
event = makeClickEventData(marker.getPosition());
|
|
1394
|
-
// todo: use Fabric events
|
|
1395
|
-
// manager.pushEvent(context, markerView, "onDrag", event);
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
@Override
|
|
1399
|
-
public void onMarkerDragEnd(Marker marker) {
|
|
1400
|
-
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1401
|
-
dispatchEvent(event, OnMarkerDragEndEvent::new);
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
MapMarker markerView = getMarkerMap(marker);
|
|
1405
|
-
event = makeClickEventData(marker.getPosition());
|
|
1406
|
-
// todo: use Fabric events
|
|
1407
|
-
// manager.pushEvent(context, markerView, "onDragEnd", event);
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
@Override
|
|
1411
|
-
public void onPoiClick(PointOfInterest poi) {
|
|
1412
|
-
WritableMap event = makeClickEventData(poi.latLng);
|
|
1413
|
-
|
|
1414
|
-
event.putString("placeId", poi.placeId);
|
|
1415
|
-
event.putString("name", poi.name);
|
|
1416
|
-
dispatchEvent(event, OnPoiClickEvent::new);
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
private ProgressBar getMapLoadingProgressBar() {
|
|
1420
|
-
if (this.mapLoadingProgressBar == null) {
|
|
1421
|
-
this.mapLoadingProgressBar = new ProgressBar(getContext());
|
|
1422
|
-
this.mapLoadingProgressBar.setIndeterminate(true);
|
|
1423
|
-
}
|
|
1424
|
-
if (this.loadingIndicatorColor != null) {
|
|
1425
|
-
this.setLoadingIndicatorColor(this.loadingIndicatorColor);
|
|
1426
|
-
}
|
|
1427
|
-
return this.mapLoadingProgressBar;
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
private RelativeLayout getMapLoadingLayoutView() {
|
|
1431
|
-
if (this.mapLoadingLayout == null) {
|
|
1432
|
-
this.mapLoadingLayout = new RelativeLayout(getContext());
|
|
1433
|
-
this.mapLoadingLayout.setBackgroundColor(Color.LTGRAY);
|
|
1434
|
-
this.addView(this.mapLoadingLayout,
|
|
1435
|
-
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
1436
|
-
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
1437
|
-
|
|
1438
|
-
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
|
|
1439
|
-
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
|
1440
|
-
params.addRule(RelativeLayout.CENTER_IN_PARENT);
|
|
1441
|
-
this.mapLoadingLayout.addView(this.getMapLoadingProgressBar(), params);
|
|
1442
|
-
|
|
1443
|
-
this.mapLoadingLayout.setVisibility(View.INVISIBLE);
|
|
1444
|
-
}
|
|
1445
|
-
this.setLoadingBackgroundColor(this.loadingBackgroundColor);
|
|
1446
|
-
return this.mapLoadingLayout;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
private ImageView getCacheImageView() {
|
|
1450
|
-
if (this.cacheImageView == null) {
|
|
1451
|
-
this.cacheImageView = new ImageView(getContext());
|
|
1452
|
-
this.addView(this.cacheImageView,
|
|
1453
|
-
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
1454
|
-
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
1455
|
-
this.cacheImageView.setVisibility(View.INVISIBLE);
|
|
1456
|
-
}
|
|
1457
|
-
return this.cacheImageView;
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
private void removeCacheImageView() {
|
|
1461
|
-
if (this.cacheImageView != null) {
|
|
1462
|
-
((ViewGroup) this.cacheImageView.getParent()).removeView(this.cacheImageView);
|
|
1463
|
-
this.cacheImageView = null;
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
private void removeMapLoadingProgressBar() {
|
|
1468
|
-
if (this.mapLoadingProgressBar != null) {
|
|
1469
|
-
((ViewGroup) this.mapLoadingProgressBar.getParent()).removeView(this.mapLoadingProgressBar);
|
|
1470
|
-
this.mapLoadingProgressBar = null;
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
private void removeMapLoadingLayoutView() {
|
|
1475
|
-
this.removeMapLoadingProgressBar();
|
|
1476
|
-
if (this.mapLoadingLayout != null) {
|
|
1477
|
-
((ViewGroup) this.mapLoadingLayout.getParent()).removeView(this.mapLoadingLayout);
|
|
1478
|
-
this.mapLoadingLayout = null;
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
private void cacheView() {
|
|
1483
|
-
if (this.cacheEnabled) {
|
|
1484
|
-
final ImageView cacheImageView = this.getCacheImageView();
|
|
1485
|
-
final RelativeLayout mapLoadingLayout = this.getMapLoadingLayoutView();
|
|
1486
|
-
cacheImageView.setVisibility(View.INVISIBLE);
|
|
1487
|
-
mapLoadingLayout.setVisibility(View.VISIBLE);
|
|
1488
|
-
if (this.isMapLoaded) {
|
|
1489
|
-
this.map.snapshot(new GoogleMap.SnapshotReadyCallback() {
|
|
1490
|
-
@Override public void onSnapshotReady(Bitmap bitmap) {
|
|
1491
|
-
cacheImageView.setImageBitmap(bitmap);
|
|
1492
|
-
cacheImageView.setVisibility(View.VISIBLE);
|
|
1493
|
-
mapLoadingLayout.setVisibility(View.INVISIBLE);
|
|
1494
|
-
}
|
|
1495
|
-
});
|
|
1496
|
-
}
|
|
1497
|
-
} else {
|
|
1498
|
-
this.removeCacheImageView();
|
|
1499
|
-
if (this.isMapLoaded) {
|
|
1500
|
-
this.removeMapLoadingLayoutView();
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
public void onPanDrag(MotionEvent ev) {
|
|
1506
|
-
Point point = new Point((int) ev.getX(), (int) ev.getY());
|
|
1507
|
-
LatLng coords = this.map.getProjection().fromScreenLocation(point);
|
|
1508
|
-
WritableMap event = makeClickEventData(coords);
|
|
1509
|
-
// todo: use Fabric events
|
|
1510
|
-
// manager.pushEvent(context, this, "onPanDrag", event);
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
public void onDoublePress(MotionEvent ev) {
|
|
1514
|
-
if (this.map == null) return;
|
|
1515
|
-
Point point = new Point((int) ev.getX(), (int) ev.getY());
|
|
1516
|
-
LatLng coords = this.map.getProjection().fromScreenLocation(point);
|
|
1517
|
-
WritableMap event = makeClickEventData(coords);
|
|
1518
|
-
// todo: use Fabric events
|
|
1519
|
-
// manager.pushEvent(context, this, "onDoublePress", event);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
public void setKmlSrc(String kmlSrc) {
|
|
1523
|
-
try {
|
|
1524
|
-
InputStream kmlStream = new FileUtil(context).execute(kmlSrc).get();
|
|
1525
|
-
|
|
1526
|
-
if (kmlStream == null) {
|
|
1527
|
-
return;
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
KmlLayer kmlLayer = new KmlLayer(map, kmlStream, context, markerManager, polygonManager, polylineManager, groundOverlayManager, null);
|
|
1531
|
-
kmlLayer.addLayerToMap();
|
|
1532
|
-
|
|
1533
|
-
WritableMap pointers = new WritableNativeMap();
|
|
1534
|
-
WritableArray markers = new WritableNativeArray();
|
|
1535
|
-
|
|
1536
|
-
if (kmlLayer.getContainers() == null) {
|
|
1453
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
1454
|
+
event = makeClickEventData(marker.getPosition());
|
|
1537
1455
|
// todo: use Fabric events
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
}
|
|
1456
|
+
// manager.pushEvent(context, markerView, "onDrag", event);
|
|
1457
|
+
}
|
|
1541
1458
|
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1459
|
+
@Override
|
|
1460
|
+
public void onMarkerDragEnd(Marker marker) {
|
|
1461
|
+
WritableMap event = makeClickEventData(marker.getPosition());
|
|
1462
|
+
dispatchEvent(event, OnMarkerDragEndEvent::new);
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
MapMarker markerView = getMarkerMap(marker);
|
|
1466
|
+
event = makeClickEventData(marker.getPosition());
|
|
1545
1467
|
// todo: use Fabric events
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1468
|
+
// manager.pushEvent(context, markerView, "onDragEnd", event);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
@Override
|
|
1472
|
+
public void onPoiClick(PointOfInterest poi) {
|
|
1473
|
+
WritableMap event = makeClickEventData(poi.latLng);
|
|
1474
|
+
|
|
1475
|
+
event.putString("placeId", poi.placeId);
|
|
1476
|
+
event.putString("name", poi.name);
|
|
1477
|
+
dispatchEvent(event, OnPoiClickEvent::new);
|
|
1478
|
+
}
|
|
1549
1479
|
|
|
1480
|
+
private ProgressBar getMapLoadingProgressBar() {
|
|
1481
|
+
if (this.mapLoadingProgressBar == null) {
|
|
1482
|
+
this.mapLoadingProgressBar = new ProgressBar(getContext());
|
|
1483
|
+
this.mapLoadingProgressBar.setIndeterminate(true);
|
|
1484
|
+
}
|
|
1485
|
+
if (this.loadingIndicatorColor != null) {
|
|
1486
|
+
this.setLoadingIndicatorColor(this.loadingIndicatorColor);
|
|
1487
|
+
}
|
|
1488
|
+
return this.mapLoadingProgressBar;
|
|
1489
|
+
}
|
|
1550
1490
|
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1491
|
+
private RelativeLayout getMapLoadingLayoutView() {
|
|
1492
|
+
if (this.mapLoadingLayout == null) {
|
|
1493
|
+
this.mapLoadingLayout = new RelativeLayout(getContext());
|
|
1494
|
+
this.mapLoadingLayout.setBackgroundColor(Color.LTGRAY);
|
|
1495
|
+
this.addView(this.mapLoadingLayout,
|
|
1496
|
+
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
1497
|
+
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
1554
1498
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1499
|
+
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
|
|
1500
|
+
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
|
1501
|
+
params.addRule(RelativeLayout.CENTER_IN_PARENT);
|
|
1502
|
+
this.mapLoadingLayout.addView(this.getMapLoadingProgressBar(), params);
|
|
1558
1503
|
|
|
1559
|
-
|
|
1560
|
-
options = placemark.getMarkerOptions();
|
|
1561
|
-
} else {
|
|
1562
|
-
options.icon(BitmapDescriptorFactory.defaultMarker());
|
|
1504
|
+
this.mapLoadingLayout.setVisibility(View.INVISIBLE);
|
|
1563
1505
|
}
|
|
1506
|
+
this.setLoadingBackgroundColor(this.loadingBackgroundColor);
|
|
1507
|
+
return this.mapLoadingLayout;
|
|
1508
|
+
}
|
|
1564
1509
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1510
|
+
private ImageView getCacheImageView() {
|
|
1511
|
+
if (this.cacheImageView == null) {
|
|
1512
|
+
this.cacheImageView = new ImageView(getContext());
|
|
1513
|
+
this.addView(this.cacheImageView,
|
|
1514
|
+
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
1515
|
+
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
1516
|
+
this.cacheImageView.setVisibility(View.INVISIBLE);
|
|
1517
|
+
}
|
|
1518
|
+
return this.cacheImageView;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
private void removeCacheImageView() {
|
|
1522
|
+
if (this.cacheImageView != null) {
|
|
1523
|
+
((ViewGroup) this.cacheImageView.getParent()).removeView(this.cacheImageView);
|
|
1524
|
+
this.cacheImageView = null;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1568
1527
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1528
|
+
private void removeMapLoadingProgressBar() {
|
|
1529
|
+
if (this.mapLoadingProgressBar != null) {
|
|
1530
|
+
((ViewGroup) this.mapLoadingProgressBar.getParent()).removeView(this.mapLoadingProgressBar);
|
|
1531
|
+
this.mapLoadingProgressBar = null;
|
|
1571
1532
|
}
|
|
1533
|
+
}
|
|
1572
1534
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1535
|
+
private void removeMapLoadingLayoutView() {
|
|
1536
|
+
this.removeMapLoadingProgressBar();
|
|
1537
|
+
if (this.mapLoadingLayout != null) {
|
|
1538
|
+
((ViewGroup) this.mapLoadingLayout.getParent()).removeView(this.mapLoadingLayout);
|
|
1539
|
+
this.mapLoadingLayout = null;
|
|
1575
1540
|
}
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
private void cacheView() {
|
|
1544
|
+
if (this.cacheEnabled) {
|
|
1545
|
+
final ImageView cacheImageView = this.getCacheImageView();
|
|
1546
|
+
final RelativeLayout mapLoadingLayout = this.getMapLoadingLayoutView();
|
|
1547
|
+
cacheImageView.setVisibility(View.INVISIBLE);
|
|
1548
|
+
mapLoadingLayout.setVisibility(View.VISIBLE);
|
|
1549
|
+
if (this.isMapLoaded) {
|
|
1550
|
+
this.map.snapshot(new GoogleMap.SnapshotReadyCallback() {
|
|
1551
|
+
@Override
|
|
1552
|
+
public void onSnapshotReady(Bitmap bitmap) {
|
|
1553
|
+
cacheImageView.setImageBitmap(bitmap);
|
|
1554
|
+
cacheImageView.setVisibility(View.VISIBLE);
|
|
1555
|
+
mapLoadingLayout.setVisibility(View.INVISIBLE);
|
|
1556
|
+
}
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1559
|
+
} else {
|
|
1560
|
+
this.removeCacheImageView();
|
|
1561
|
+
if (this.isMapLoaded) {
|
|
1562
|
+
this.removeMapLoadingLayoutView();
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
public void onPanDrag(MotionEvent ev) {
|
|
1568
|
+
Point point = new Point((int) ev.getX(), (int) ev.getY());
|
|
1569
|
+
LatLng coords = this.map.getProjection().fromScreenLocation(point);
|
|
1570
|
+
WritableMap event = makeClickEventData(coords);
|
|
1571
|
+
// todo: use Fabric events
|
|
1572
|
+
// manager.pushEvent(context, this, "onPanDrag", event);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
public void onDoublePress(MotionEvent ev) {
|
|
1576
|
+
if (this.map == null) return;
|
|
1577
|
+
Point point = new Point((int) ev.getX(), (int) ev.getY());
|
|
1578
|
+
LatLng coords = this.map.getProjection().fromScreenLocation(point);
|
|
1579
|
+
WritableMap event = makeClickEventData(coords);
|
|
1580
|
+
// todo: use Fabric events
|
|
1581
|
+
// manager.pushEvent(context, this, "onDoublePress", event);
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
public void setKmlSrc(String kmlSrc) {
|
|
1585
|
+
try {
|
|
1586
|
+
InputStream kmlStream = new FileUtil(context).execute(kmlSrc).get();
|
|
1587
|
+
|
|
1588
|
+
if (kmlStream == null) {
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
KmlLayer kmlLayer = new KmlLayer(map, kmlStream, context, markerManager, polygonManager, polylineManager, groundOverlayManager, null);
|
|
1593
|
+
kmlLayer.addLayerToMap();
|
|
1594
|
+
|
|
1595
|
+
WritableMap pointers = new WritableNativeMap();
|
|
1596
|
+
WritableArray markers = new WritableNativeArray();
|
|
1597
|
+
|
|
1598
|
+
if (kmlLayer.getContainers() == null) {
|
|
1599
|
+
// todo: use Fabric events
|
|
1600
|
+
// manager.pushEvent(context, this, "onKmlReady", pointers);
|
|
1601
|
+
return;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
//Retrieve a nested container within the first container
|
|
1605
|
+
KmlContainer container = kmlLayer.getContainers().iterator().next();
|
|
1606
|
+
if (container == null || container.getContainers() == null) {
|
|
1607
|
+
// todo: use Fabric events
|
|
1608
|
+
// manager.pushEvent(context, this, "onKmlReady", pointers);
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1576
1612
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1613
|
+
if (container.getContainers().iterator().hasNext()) {
|
|
1614
|
+
container = container.getContainers().iterator().next();
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
int index = 0;
|
|
1618
|
+
for (KmlPlacemark placemark : container.getPlacemarks()) {
|
|
1619
|
+
MarkerOptions options = new MarkerOptions();
|
|
1620
|
+
|
|
1621
|
+
if (placemark.getInlineStyle() != null) {
|
|
1622
|
+
options = placemark.getMarkerOptions();
|
|
1623
|
+
} else {
|
|
1624
|
+
options.icon(BitmapDescriptorFactory.defaultMarker());
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
LatLng latLng = ((LatLng) placemark.getGeometry().getGeometryObject());
|
|
1628
|
+
String title = "";
|
|
1629
|
+
String snippet = "";
|
|
1630
|
+
|
|
1631
|
+
if (placemark.hasProperty("name")) {
|
|
1632
|
+
title = placemark.getProperty("name");
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
if (placemark.hasProperty("description")) {
|
|
1636
|
+
snippet = placemark.getProperty("description");
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
options.position(latLng);
|
|
1640
|
+
options.title(title);
|
|
1641
|
+
options.snippet(snippet);
|
|
1642
|
+
// FIXME: get markerManager from somewhere
|
|
1581
1643
|
/*
|
|
1582
1644
|
MapMarker marker = new MapMarker(context, options, this.manager.getMarkerManager());
|
|
1583
1645
|
|
|
@@ -1603,121 +1665,122 @@ public static CameraPosition cameraPositionFromMap(ReadableMap camera){
|
|
|
1603
1665
|
|
|
1604
1666
|
markers.pushMap(loadedMarker);
|
|
1605
1667
|
*/
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
@Override
|
|
1656
|
-
public void onIndoorLevelActivated(IndoorBuilding building) {
|
|
1657
|
-
if (building == null) {
|
|
1658
|
-
return;
|
|
1659
|
-
}
|
|
1660
|
-
int activeLevelIndex = building.getActiveLevelIndex();
|
|
1661
|
-
if (activeLevelIndex < 0 || activeLevelIndex >= building.getLevels().size()) {
|
|
1662
|
-
return;
|
|
1663
|
-
}
|
|
1664
|
-
IndoorLevel level = building.getLevels().get(activeLevelIndex);
|
|
1665
|
-
|
|
1666
|
-
WritableMap event = Arguments.createMap();
|
|
1667
|
-
WritableMap indoorlevel = Arguments.createMap();
|
|
1668
|
-
|
|
1669
|
-
indoorlevel.putInt("activeLevelIndex", activeLevelIndex);
|
|
1670
|
-
indoorlevel.putString("name", level.getName());
|
|
1671
|
-
indoorlevel.putString("shortName", level.getShortName());
|
|
1672
|
-
|
|
1673
|
-
event.putMap("IndoorLevel", indoorlevel);
|
|
1674
|
-
// todo: use Fabric events
|
|
1675
|
-
// manager.pushEvent(context, this, "onIndoorLevelActivated", event);
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
public void setIndoorActiveLevelIndex(int activeLevelIndex) {
|
|
1679
|
-
IndoorBuilding building = this.map.getFocusedBuilding();
|
|
1680
|
-
if (building != null) {
|
|
1681
|
-
if (activeLevelIndex >= 0 && activeLevelIndex < building.getLevels().size()) {
|
|
1682
|
-
IndoorLevel level = building.getLevels().get(activeLevelIndex);
|
|
1683
|
-
if (level != null) {
|
|
1684
|
-
level.activate();
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
pointers.putArray("markers", markers);
|
|
1671
|
+
// todo: use Fabric events
|
|
1672
|
+
// manager.pushEvent(context, this, "onKmlReady", pointers);
|
|
1673
|
+
|
|
1674
|
+
} catch (XmlPullParserException | IOException | InterruptedException |
|
|
1675
|
+
ExecutionException e) {
|
|
1676
|
+
e.printStackTrace();
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
@Override
|
|
1681
|
+
public void onIndoorBuildingFocused() {
|
|
1682
|
+
IndoorBuilding building = this.map.getFocusedBuilding();
|
|
1683
|
+
if (building != null) {
|
|
1684
|
+
List<IndoorLevel> levels = building.getLevels();
|
|
1685
|
+
int index = 0;
|
|
1686
|
+
WritableArray levelsArray = Arguments.createArray();
|
|
1687
|
+
for (IndoorLevel level : levels) {
|
|
1688
|
+
WritableMap levelMap = Arguments.createMap();
|
|
1689
|
+
levelMap.putInt("index", index);
|
|
1690
|
+
levelMap.putString("name", level.getName());
|
|
1691
|
+
levelMap.putString("shortName", level.getShortName());
|
|
1692
|
+
levelsArray.pushMap(levelMap);
|
|
1693
|
+
index++;
|
|
1694
|
+
}
|
|
1695
|
+
WritableMap event = Arguments.createMap();
|
|
1696
|
+
WritableMap indoorBuilding = Arguments.createMap();
|
|
1697
|
+
indoorBuilding.putArray("levels", levelsArray);
|
|
1698
|
+
indoorBuilding.putInt("activeLevelIndex", building.getActiveLevelIndex());
|
|
1699
|
+
indoorBuilding.putBoolean("underground", building.isUnderground());
|
|
1700
|
+
|
|
1701
|
+
event.putMap("IndoorBuilding", indoorBuilding);
|
|
1702
|
+
// todo: use Fabric events
|
|
1703
|
+
// manager.pushEvent(context, this, "onIndoorBuildingFocused", event);
|
|
1704
|
+
} else {
|
|
1705
|
+
WritableMap event = Arguments.createMap();
|
|
1706
|
+
WritableArray levelsArray = Arguments.createArray();
|
|
1707
|
+
WritableMap indoorBuilding = Arguments.createMap();
|
|
1708
|
+
indoorBuilding.putArray("levels", levelsArray);
|
|
1709
|
+
indoorBuilding.putInt("activeLevelIndex", 0);
|
|
1710
|
+
indoorBuilding.putBoolean("underground", false);
|
|
1711
|
+
|
|
1712
|
+
event.putMap("IndoorBuilding", indoorBuilding);
|
|
1713
|
+
// todo: use Fabric events
|
|
1714
|
+
// manager.pushEvent(context, this, "onIndoorBuildingFocused", event);
|
|
1685
1715
|
}
|
|
1686
|
-
}
|
|
1687
1716
|
}
|
|
1688
|
-
}
|
|
1689
1717
|
|
|
1690
|
-
|
|
1691
|
-
|
|
1718
|
+
@Override
|
|
1719
|
+
public void onIndoorLevelActivated(IndoorBuilding building) {
|
|
1720
|
+
if (building == null) {
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1723
|
+
int activeLevelIndex = building.getActiveLevelIndex();
|
|
1724
|
+
if (activeLevelIndex < 0 || activeLevelIndex >= building.getLevels().size()) {
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
IndoorLevel level = building.getLevels().get(activeLevelIndex);
|
|
1728
|
+
|
|
1729
|
+
WritableMap event = Arguments.createMap();
|
|
1730
|
+
WritableMap indoorlevel = Arguments.createMap();
|
|
1731
|
+
|
|
1732
|
+
indoorlevel.putInt("activeLevelIndex", activeLevelIndex);
|
|
1733
|
+
indoorlevel.putString("name", level.getName());
|
|
1734
|
+
indoorlevel.putString("shortName", level.getShortName());
|
|
1692
1735
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1736
|
+
event.putMap("IndoorLevel", indoorlevel);
|
|
1737
|
+
// todo: use Fabric events
|
|
1738
|
+
// manager.pushEvent(context, this, "onIndoorLevelActivated", event);
|
|
1695
1739
|
}
|
|
1696
1740
|
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1741
|
+
public void setIndoorActiveLevelIndex(int activeLevelIndex) {
|
|
1742
|
+
IndoorBuilding building = this.map.getFocusedBuilding();
|
|
1743
|
+
if (building != null) {
|
|
1744
|
+
if (activeLevelIndex >= 0 && activeLevelIndex < building.getLevels().size()) {
|
|
1745
|
+
IndoorLevel level = building.getLevels().get(activeLevelIndex);
|
|
1746
|
+
if (level != null) {
|
|
1747
|
+
level.activate();
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1703
1751
|
}
|
|
1704
1752
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1753
|
+
private MapMarker getMarkerMap(Marker marker) {
|
|
1754
|
+
MapMarker airMarker = markerMap.get(marker);
|
|
1707
1755
|
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1756
|
+
if (airMarker != null) {
|
|
1757
|
+
return airMarker;
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
for (Map.Entry<Marker, MapMarker> entryMarker : markerMap.entrySet()) {
|
|
1761
|
+
if (entryMarker.getKey().getPosition().equals(marker.getPosition())
|
|
1762
|
+
&& entryMarker.getKey().getTitle().equals(marker.getTitle())) {
|
|
1763
|
+
airMarker = entryMarker.getValue();
|
|
1764
|
+
break;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
return airMarker;
|
|
1769
|
+
}
|
|
1713
1770
|
|
|
1714
|
-
private final Runnable measureAndLayout = new Runnable() {
|
|
1715
1771
|
@Override
|
|
1716
|
-
public void
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
layout(getLeft(), getTop(), getRight(), getBottom());
|
|
1772
|
+
public void requestLayout() {
|
|
1773
|
+
super.requestLayout();
|
|
1774
|
+
post(measureAndLayout);
|
|
1720
1775
|
}
|
|
1721
|
-
|
|
1776
|
+
|
|
1777
|
+
private final Runnable measureAndLayout = new Runnable() {
|
|
1778
|
+
@Override
|
|
1779
|
+
public void run() {
|
|
1780
|
+
measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
|
1781
|
+
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
|
1782
|
+
layout(getLeft(), getTop(), getRight(), getBottom());
|
|
1783
|
+
}
|
|
1784
|
+
};
|
|
1722
1785
|
|
|
1723
1786
|
}
|