/* * 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.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import pl.mg6.android.maps.extensions.AnimationSettings; import pl.mg6.android.maps.extensions.ClusteringSettings; import pl.mg6.android.maps.extensions.Marker; import pl.mg6.android.maps.extensions.MarkerOptions; import pl.mg6.android.maps.extensions.lazy.LazyMarker; import pl.mg6.android.maps.extensions.lazy.LazyMarker.OnMarkerCreateListener; import android.os.SystemClock; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; class MarkerManager implements OnMarkerCreateListener { private final IGoogleMap factory; private final Map<LazyMarker, DelegatingMarker> markers; private final Map<com.google.android.gms.maps.model.Marker, LazyMarker> createdMarkers; private Marker markerShowingInfoWindow; private ClusteringSettings clusteringSettings = new ClusteringSettings().enabled(false); private ClusteringStrategy clusteringStrategy = new NoClusteringStrategy(new ArrayList<DelegatingMarker>()); private final MarkerAnimator markerAnimator = new MarkerAnimator(); public MarkerManager(IGoogleMap factory) { this.factory = factory; this.markers = new HashMap<LazyMarker, DelegatingMarker>(); this.createdMarkers = new HashMap<com.google.android.gms.maps.model.Marker, LazyMarker>(); } public Marker addMarker(MarkerOptions markerOptions) { boolean visible = markerOptions.isVisible(); markerOptions.visible(false); DelegatingMarker marker = createMarker(markerOptions.real); setExtendedOptions(marker, markerOptions); clusteringStrategy.onAdd(marker); marker.setVisible(visible); markerOptions.visible(visible); return marker; } private void setExtendedOptions(DelegatingMarker marker, MarkerOptions markerOptions) { marker.setClusterGroup(markerOptions.getClusterGroup()); marker.setData(markerOptions.getData()); } public Marker addMarker(com.google.android.gms.maps.model.MarkerOptions markerOptions) { boolean visible = markerOptions.isVisible(); markerOptions.visible(false); DelegatingMarker marker = createMarker(markerOptions); clusteringStrategy.onAdd(marker); marker.setVisible(visible); markerOptions.visible(visible); return marker; } private DelegatingMarker createMarker(com.google.android.gms.maps.model.MarkerOptions markerOptions) { LazyMarker realMarker = new LazyMarker(factory.getMap(), markerOptions, this); DelegatingMarker marker = new DelegatingMarker(realMarker, this); markers.put(realMarker, marker); return marker; } public void clear() { markers.clear(); createdMarkers.clear(); clusteringStrategy.cleanup(); } public List<Marker> getDisplayedMarkers() { List<Marker> displayedMarkers = clusteringStrategy.getDisplayedMarkers(); if (displayedMarkers == null) { displayedMarkers = getMarkers(); Iterator<Marker> iterator = displayedMarkers.iterator(); while (iterator.hasNext()) { Marker m = iterator.next(); if (!m.isVisible()) { iterator.remove(); } } } return displayedMarkers; } public List<Marker> getMarkers() { return new ArrayList<Marker>(markers.values()); } public Marker getMarkerShowingInfoWindow() { if (markerShowingInfoWindow != null && !markerShowingInfoWindow.isInfoWindowShown()) { markerShowingInfoWindow = null; } return markerShowingInfoWindow; } public float getMinZoomLevelNotClustered(Marker marker) { return clusteringStrategy.getMinZoomLevelNotClustered(marker); } public void onAnimateMarkerPosition(DelegatingMarker marker, LatLng target, AnimationSettings settings, Marker.AnimationCallback callback) { markerAnimator.cancelAnimation(marker, Marker.AnimationCallback.CancelReason.ANIMATE_POSITION); markerAnimator.animate(marker, marker.getPosition(), target, SystemClock.uptimeMillis(), settings, callback); } public void onCameraChange(CameraPosition cameraPosition) { clusteringStrategy.onCameraChange(cameraPosition); } public void onClusterGroupChange(DelegatingMarker marker) { clusteringStrategy.onClusterGroupChange(marker); } public void onDragStart(DelegatingMarker marker) { markerAnimator.cancelAnimation(marker, Marker.AnimationCallback.CancelReason.DRAG_START); } public void onPositionChange(DelegatingMarker marker) { clusteringStrategy.onPositionChange(marker); markerAnimator.cancelAnimation(marker, Marker.AnimationCallback.CancelReason.SET_POSITION); } public void onPositionDuringAnimationChange(DelegatingMarker marker) { clusteringStrategy.onPositionChange(marker); } public void onRemove(DelegatingMarker marker) { markers.remove(marker.getReal()); createdMarkers.remove(marker.getReal().getMarker()); clusteringStrategy.onRemove(marker); markerAnimator.cancelAnimation(marker, Marker.AnimationCallback.CancelReason.REMOVE); } public void onShowInfoWindow(DelegatingMarker marker) { clusteringStrategy.onShowInfoWindow(marker); } public void onVisibilityChangeRequest(DelegatingMarker marker, boolean visible) { clusteringStrategy.onVisibilityChangeRequest(marker, visible); } public void setClustering(ClusteringSettings clusteringSettings) { if (clusteringSettings == null) { clusteringSettings = new ClusteringSettings().enabled(false); } if (!this.clusteringSettings.equals(clusteringSettings)) { this.clusteringSettings = clusteringSettings; clusteringStrategy.cleanup(); ArrayList<DelegatingMarker> list = new ArrayList<DelegatingMarker>(markers.values()); if (clusteringSettings.isEnabled()) { clusteringStrategy = new GridClusteringStrategy(clusteringSettings, factory, list, new ClusterRefresher()); } else if (clusteringSettings.isAddMarkersDynamically()) { clusteringStrategy = new DynamicNoClusteringStrategy(factory, list); } else { clusteringStrategy = new NoClusteringStrategy(list); } } } public void setMarkerShowingInfoWindow(Marker marker) { this.markerShowingInfoWindow = marker; } @Override public void onMarkerCreate(LazyMarker marker) { createdMarkers.put(marker.getMarker(), marker); } public Marker map(com.google.android.gms.maps.model.Marker marker) { Marker cluster = clusteringStrategy.map(marker); if (cluster != null) { return cluster; } return mapToDelegatingMarker(marker); } public DelegatingMarker mapToDelegatingMarker(com.google.android.gms.maps.model.Marker marker) { LazyMarker lazy = createdMarkers.get(marker); DelegatingMarker delegating = markers.get(lazy); return delegating; } }