/* * Copyright (C) 2013 Maciej Górski * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package pl.mg6.android.maps.extensions.impl; import java.util.List; import pl.mg6.android.maps.extensions.Circle; import pl.mg6.android.maps.extensions.CircleOptions; import pl.mg6.android.maps.extensions.ClusteringSettings; import pl.mg6.android.maps.extensions.DefaultClusterOptionsProvider; import pl.mg6.android.maps.extensions.GoogleMap; import pl.mg6.android.maps.extensions.GroundOverlay; import pl.mg6.android.maps.extensions.GroundOverlayOptions; import pl.mg6.android.maps.extensions.Marker; import pl.mg6.android.maps.extensions.MarkerOptions; import pl.mg6.android.maps.extensions.Polygon; import pl.mg6.android.maps.extensions.PolygonOptions; import pl.mg6.android.maps.extensions.Polyline; import pl.mg6.android.maps.extensions.PolylineOptions; import pl.mg6.android.maps.extensions.TileOverlay; import pl.mg6.android.maps.extensions.TileOverlayOptions; import android.content.Context; import android.graphics.Bitmap; import android.location.Location; import android.view.View; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.LocationSource; import com.google.android.gms.maps.Projection; import com.google.android.gms.maps.UiSettings; import com.google.android.gms.maps.model.CameraPosition; class DelegatingGoogleMap implements GoogleMap { private IGoogleMap real; private Context context; private InfoWindowAdapter infoWindowAdapter; private OnCameraChangeListener onCameraChangeListener; private OnMarkerDragListener onMarkerDragListener; private MarkerManager markerManager; private PolylineManager polylineManager; private PolygonManager polygonManager; private CircleManager circleManager; private GroundOverlayManager groundOverlayManager; private TileOverlayManager tileOverlayManager; DelegatingGoogleMap(com.google.android.gms.maps.GoogleMap real, Context context) { this.real = new GoogleMapWrapper(real); this.context = context; createManagers(); assignMapListeners(); } @Override public Circle addCircle(CircleOptions circleOptions) { return circleManager.addCircle(circleOptions); } @Deprecated @Override public Circle addCircle(com.google.android.gms.maps.model.CircleOptions circleOptions) { return circleManager.addCircle(circleOptions); } @Override public GroundOverlay addGroundOverlay(GroundOverlayOptions groundOverlayOptions) { return groundOverlayManager.addGroundOverlay(groundOverlayOptions); } @Deprecated @Override public GroundOverlay addGroundOverlay(com.google.android.gms.maps.model.GroundOverlayOptions groundOverlayOptions) { return groundOverlayManager.addGroundOverlay(groundOverlayOptions); } @Override public Marker addMarker(MarkerOptions markerOptions) { return markerManager.addMarker(markerOptions); } @Deprecated @Override public Marker addMarker(com.google.android.gms.maps.model.MarkerOptions markerOptions) { return markerManager.addMarker(markerOptions); } @Override public Polygon addPolygon(PolygonOptions polygonOptions) { return polygonManager.addPolygon(polygonOptions); } @Deprecated @Override public Polygon addPolygon(com.google.android.gms.maps.model.PolygonOptions polygonOptions) { return polygonManager.addPolygon(polygonOptions); } @Override public Polyline addPolyline(PolylineOptions polylineOptions) { return polylineManager.addPolyline(polylineOptions); } @Deprecated @Override public Polyline addPolyline(com.google.android.gms.maps.model.PolylineOptions polylineOptions) { return polylineManager.addPolyline(polylineOptions); } @Override public TileOverlay addTileOverlay(TileOverlayOptions tileOverlayOptions) { return tileOverlayManager.addTileOverlay(tileOverlayOptions); } @Deprecated @Override public TileOverlay addTileOverlay(com.google.android.gms.maps.model.TileOverlayOptions tileOverlayOptions) { return tileOverlayManager.addTileOverlay(tileOverlayOptions); } @Override public void animateCamera(CameraUpdate cameraUpdate, CancelableCallback cancelableCallback) { real.animateCamera(cameraUpdate, cancelableCallback); } @Override public void animateCamera(CameraUpdate cameraUpdate, int time, CancelableCallback cancelableCallback) { real.animateCamera(cameraUpdate, time, cancelableCallback); } @Override public void animateCamera(CameraUpdate cameraUpdate) { real.animateCamera(cameraUpdate); } @Override public void clear() { real.clear(); clearManagers(); } @Override public CameraPosition getCameraPosition() { return real.getCameraPosition(); } @Override public List<Marker> getDisplayedMarkers() { return markerManager.getDisplayedMarkers(); } @Override public int getMapType() { return real.getMapType(); } @Override public List<Circle> getCircles() { return circleManager.getCircles(); } @Override public List<GroundOverlay> getGroundOverlays() { return groundOverlayManager.getGroundOverlays(); } @Override public List<Marker> getMarkers() { return markerManager.getMarkers(); } @Override public Marker getMarkerShowingInfoWindow() { return markerManager.getMarkerShowingInfoWindow(); } @Override public List<Polygon> getPolygons() { return polygonManager.getPolygons(); } @Override public List<Polyline> getPolylines() { return polylineManager.getPolylines(); } @Override public List<TileOverlay> getTileOverlays() { return tileOverlayManager.getTileOverlays(); } @Override public float getMaxZoomLevel() { return real.getMaxZoomLevel(); } @Override public float getMinZoomLevel() { return real.getMinZoomLevel(); } @Override public float getMinZoomLevelNotClustered(Marker marker) { return markerManager.getMinZoomLevelNotClustered(marker); } @Override public Location getMyLocation() { return real.getMyLocation(); } @Override public Projection getProjection() { return real.getProjection().getProjection(); } @Override public UiSettings getUiSettings() { return real.getUiSettings(); } @Override public boolean isIndoorEnabled() { return real.isIndoorEnabled(); } @Override public boolean isMyLocationEnabled() { return real.isMyLocationEnabled(); } @Override public boolean isTrafficEnabled() { return real.isTrafficEnabled(); } @Override public void moveCamera(CameraUpdate cameraUpdate) { real.moveCamera(cameraUpdate); } @Override public void setClustering(ClusteringSettings clusteringSettings) { if (clusteringSettings != null && clusteringSettings.isEnabled() && clusteringSettings.getIconDataProvider() == null && clusteringSettings.getClusterOptionsProvider() == null) { clusteringSettings.clusterOptionsProvider(new DefaultClusterOptionsProvider(context.getResources())); } markerManager.setClustering(clusteringSettings); } @Override public boolean setIndoorEnabled(boolean indoorEnabled) { return real.setIndoorEnabled(indoorEnabled); } @Override public void setInfoWindowAdapter(final InfoWindowAdapter infoWindowAdapter) { this.infoWindowAdapter = infoWindowAdapter; } @Override public void setLocationSource(LocationSource locationSource) { real.setLocationSource(locationSource); } @Override public void setMapType(int mapType) { real.setMapType(mapType); } @Override public void setMyLocationEnabled(boolean myLocationEnabled) { real.setMyLocationEnabled(myLocationEnabled); } @Override public void setOnCameraChangeListener(OnCameraChangeListener onCameraChangeListener) { this.onCameraChangeListener = onCameraChangeListener; } @Override public void setOnInfoWindowClickListener(OnInfoWindowClickListener onInfoWindowClickListener) { com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener realOnInfoWindowClickListener = null; if (onInfoWindowClickListener != null) { realOnInfoWindowClickListener = new DelegatingOnInfoWindowClickListener(onInfoWindowClickListener); } real.setOnInfoWindowClickListener(realOnInfoWindowClickListener); } @Override public void setOnMapClickListener(OnMapClickListener onMapClickListener) { real.setOnMapClickListener(onMapClickListener); } @Override public void setOnMapLongClickListener(OnMapLongClickListener onMapLongClickListener) { real.setOnMapLongClickListener(onMapLongClickListener); } @Override public void setOnMarkerClickListener(OnMarkerClickListener onMarkerClickListener) { com.google.android.gms.maps.GoogleMap.OnMarkerClickListener realOnMarkerClickListener = null; if (onMarkerClickListener != null) { realOnMarkerClickListener = new DelegatingOnMarkerClickListener(onMarkerClickListener); } real.setOnMarkerClickListener(realOnMarkerClickListener); } @Override public void setOnMarkerDragListener(OnMarkerDragListener onMarkerDragListener) { this.onMarkerDragListener = onMarkerDragListener; } @Override public void setOnMyLocationButtonClickListener(OnMyLocationButtonClickListener listener) { real.setOnMyLocationButtonClickListener(listener); } @Override public void setOnMyLocationChangeListener(OnMyLocationChangeListener onMyLocationChangeListener) { real.setOnMyLocationChangeListener(onMyLocationChangeListener); } @Override public void setPadding(int left, int top, int right, int bottom) { real.setPadding(left, top, right, bottom); } @Override public void setTrafficEnabled(boolean trafficEnabled) { real.setTrafficEnabled(trafficEnabled); } @Override public void snapshot(SnapshotReadyCallback callback) { real.snapshot(callback); } @Override public void snapshot(SnapshotReadyCallback callback, Bitmap bitmap) { real.snapshot(callback, bitmap); } @Override public void stopAnimation() { real.stopAnimation(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof DelegatingGoogleMap)) { return false; } DelegatingGoogleMap other = (DelegatingGoogleMap) o; return real.equals(other.real); } @Override public int hashCode() { return real.hashCode(); } @Override public String toString() { return real.toString(); } private void createManagers() { markerManager = new MarkerManager(this.real); polylineManager = new PolylineManager(this.real); polygonManager = new PolygonManager(this.real); circleManager = new CircleManager(this.real); groundOverlayManager = new GroundOverlayManager(this.real); tileOverlayManager = new TileOverlayManager(this.real); } private void clearManagers() { markerManager.clear(); polylineManager.clear(); polygonManager.clear(); circleManager.clear(); groundOverlayManager.clear(); tileOverlayManager.clear(); } private void assignMapListeners() { real.setInfoWindowAdapter(new DelegatingInfoWindowAdapter()); real.setOnCameraChangeListener(new DelegatingOnCameraChangeListener()); real.setOnMarkerDragListener(new DelegatingOnMarkerDragListener()); } private class DelegatingOnCameraChangeListener implements com.google.android.gms.maps.GoogleMap.OnCameraChangeListener { @Override public void onCameraChange(CameraPosition cameraPosition) { markerManager.onCameraChange(cameraPosition); if (onCameraChangeListener != null) { onCameraChangeListener.onCameraChange(cameraPosition); } } } private class DelegatingInfoWindowAdapter implements com.google.android.gms.maps.GoogleMap.InfoWindowAdapter { @Override public View getInfoWindow(com.google.android.gms.maps.model.Marker marker) { Marker mapped = markerManager.map(marker); markerManager.setMarkerShowingInfoWindow(mapped); if (infoWindowAdapter != null) { return infoWindowAdapter.getInfoWindow(mapped); } return null; } @Override public View getInfoContents(com.google.android.gms.maps.model.Marker marker) { if (infoWindowAdapter != null) { return infoWindowAdapter.getInfoContents(markerManager.map(marker)); } return null; } } private class DelegatingOnInfoWindowClickListener implements com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener { private final OnInfoWindowClickListener onInfoWindowClickListener; public DelegatingOnInfoWindowClickListener(OnInfoWindowClickListener onInfoWindowClickListener) { this.onInfoWindowClickListener = onInfoWindowClickListener; } @Override public void onInfoWindowClick(com.google.android.gms.maps.model.Marker marker) { onInfoWindowClickListener.onInfoWindowClick(markerManager.map(marker)); } } private class DelegatingOnMarkerClickListener implements com.google.android.gms.maps.GoogleMap.OnMarkerClickListener { private final OnMarkerClickListener onMarkerClickListener; public DelegatingOnMarkerClickListener(OnMarkerClickListener onMarkerClickListener) { this.onMarkerClickListener = onMarkerClickListener; } @Override public boolean onMarkerClick(com.google.android.gms.maps.model.Marker marker) { return onMarkerClickListener.onMarkerClick(markerManager.map(marker)); } } private class DelegatingOnMarkerDragListener implements com.google.android.gms.maps.GoogleMap.OnMarkerDragListener { @Override public void onMarkerDragStart(com.google.android.gms.maps.model.Marker marker) { DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker); delegating.clearCachedPosition(); markerManager.onDragStart(delegating); if (onMarkerDragListener != null) { onMarkerDragListener.onMarkerDragStart(delegating); } } @Override public void onMarkerDrag(com.google.android.gms.maps.model.Marker marker) { DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker); delegating.clearCachedPosition(); if (onMarkerDragListener != null) { onMarkerDragListener.onMarkerDrag(delegating); } } @Override public void onMarkerDragEnd(com.google.android.gms.maps.model.Marker marker) { DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker); delegating.clearCachedPosition(); markerManager.onPositionChange(delegating); if (onMarkerDragListener != null) { onMarkerDragListener.onMarkerDragEnd(delegating); } } } }