package cgeo.geocaching.maps.mapsforge.v6.caches;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.location.Viewport;
import cgeo.geocaching.maps.mapsforge.v6.MapHandlers;
import cgeo.geocaching.maps.mapsforge.v6.MfMapView;
import cgeo.geocaching.models.Geocache;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.storage.DataStore;
import cgeo.geocaching.utils.Log;
import android.support.annotation.NonNull;
import java.lang.ref.WeakReference;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.mapsforge.map.layer.Layer;
public class StoredCachesOverlay extends AbstractCachesOverlay {
private final Disposable timer;
public StoredCachesOverlay(final int overlayId, final Set<GeoEntry> geoEntries, final MfMapView mapView, final Layer anchorLayer, final MapHandlers mapHandlers) {
super(overlayId, geoEntries, mapView, anchorLayer, mapHandlers);
this.timer = startTimer();
}
private Disposable startTimer() {
return Schedulers.newThread().schedulePeriodicallyDirect(new LoadTimerAction(this), 0, 250, TimeUnit.MILLISECONDS);
}
private static final class LoadTimerAction implements Runnable {
@NonNull private final WeakReference<StoredCachesOverlay> overlayRef;
private int previousZoom = -100;
private Viewport previousViewport;
LoadTimerAction(@NonNull final StoredCachesOverlay overlay) {
this.overlayRef = new WeakReference<>(overlay);
}
@Override
public void run() {
final StoredCachesOverlay overlay = overlayRef.get();
if (overlay == null) {
return;
}
try {
// get current viewport
final Viewport viewportNow = overlay.getViewport();
// Since zoomNow is used only for local comparison purposes,
// it is ok to use the Google Maps compatible zoom level of OSM Maps
final int zoomNow = overlay.getMapZoomLevel();
// check if map moved or zoomed
//TODO Portree Use Rectangle inside with bigger search window. That will stop reloading on every move
final boolean moved = overlay.isInvalidated() || previousViewport == null || zoomNow != previousZoom ||
mapMoved(previousViewport, viewportNow) || !previousViewport.includes(viewportNow);
// save new values
if (moved) {
previousZoom = zoomNow;
previousViewport = viewportNow;
overlay.load();
overlay.refreshed();
}
} catch (final Exception e) {
Log.w("StoredCachesOverlay.startLoadtimer.start", e);
}
}
}
private void load() {
try {
showProgress();
final SearchResult searchResult = new SearchResult(DataStore.loadCachedInViewport(getViewport().resize(1.2), Settings.getCacheType()));
final Set<Geocache> cachesFromSearchResult = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS);
filter(cachesFromSearchResult);
// render
fill(cachesFromSearchResult);
} finally {
hideProgress();
}
}
@Override
public void onDestroy() {
timer.dispose();
super.onDestroy();
}
}