diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2014-08-01 15:03:04 +0200 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2014-08-01 15:03:04 +0200 |
| commit | 4b1662941b47f76c3a01535df8dcf4b17de2b71f (patch) | |
| tree | a95971df14221b2b9a52958c3f15713936d5c337 | |
| parent | 1d0244099aa71931bdc20563fc2fe6f6910f6fea (diff) | |
| download | cgeo-4b1662941b47f76c3a01535df8dcf4b17de2b71f.zip cgeo-4b1662941b47f76c3a01535df8dcf4b17de2b71f.tar.gz cgeo-4b1662941b47f76c3a01535df8dcf4b17de2b71f.tar.bz2 | |
Put map drawing utilities into their own utility class
| -rw-r--r-- | main/src/cgeo/geocaching/maps/CGeoMap.java | 91 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/MapUtils.java | 126 |
2 files changed, 130 insertions, 87 deletions
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 1ec3f97..e92efc9 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -40,10 +40,10 @@ import cgeo.geocaching.utils.AngleUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.LeastRecentlyUsedSet; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.MapUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.HashCodeBuilder; import org.eclipse.jdt.annotation.NonNull; import rx.Subscription; @@ -172,15 +172,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory { private volatile long loadThreadRun = 0L; //Interthread communication flag private volatile boolean downloaded = false; - // data for overlays - private static final int[][] INSET_RELIABLE = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; // center, 33x40 / 45x51 / 60x68 - private static final int[][] INSET_TYPE = { { 5, 8, 6, 10 }, { 4, 4, 5, 11 }, { 4, 4, 5, 11 } }; // center, 22x22 / 36x36 - private static final int[][] INSET_OWN = { { 21, 0, 0, 26 }, { 25, 0, 0, 35 }, { 40, 0, 0, 48 } }; // top right, 12x12 / 16x16 / 20x20 - private static final int[][] INSET_FOUND = { { 0, 0, 21, 28 }, { 0, 0, 25, 35 }, { 0, 0, 40, 48 } }; // top left, 12x12 / 16x16 / 20x20 - private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 }, { 25, 33, 0, 0 } }; // bottom right, 12x12 / 26x26 / 35x35 - - private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 }, { 0, 33, 25, 0 } }; // bottom left, 12x12 / 26x26 / 35x35 - private final SparseArray<LayerDrawable> overlaysCache = new SparseArray<>(); + /** Count of caches currently visible */ private int cachesCnt = 0; /** List of waypoints in the viewport */ @@ -579,7 +571,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory { mapView.destroyDrawingCache(); - overlaysCache.clear(); + MapUtils.clearCachedItems(); super.onPause(); } @@ -1650,85 +1642,10 @@ public class CGeoMap extends AbstractMap implements ViewFactory { private CachesOverlayItemImpl getCacheItem(final Geocache cache) { final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(cache, cache.applyDistanceRule()); - - final int hashcode = new HashCodeBuilder() - .append(cache.isReliableLatLon()) - .append(cache.getType().id) - .append(cache.isDisabled() || cache.isArchived()) - .append(cache.getMapMarkerId()) - .append(cache.isOwner()) - .append(cache.isFound()) - .append(cache.hasUserModifiedCoords()) - .append(cache.getPersonalNote()) - .append(cache.isLogOffline()) - .append(cache.getListId() > 0) - .toHashCode(); - - LayerDrawable drawable = overlaysCache.get(hashcode); - if (drawable == null) { - drawable = createCacheItem(cache, hashcode); - } - item.setMarker(drawable); + item.setMarker(MapUtils.getCacheItem(getResources(), cache)); return item; } - private LayerDrawable createCacheItem(final Geocache cache, final int hashcode) { - // Set initial capacities to the maximum of layers and insets to avoid dynamic reallocation - final ArrayList<Drawable> layers = new ArrayList<>(9); - final ArrayList<int[]> insets = new ArrayList<>(8); - - // background: disabled or not - final Drawable marker = getResources().getDrawable(cache.getMapMarkerId()); - layers.add(marker); - final int resolution = marker.getIntrinsicWidth() > 40 ? (marker.getIntrinsicWidth() > 50 ? 2 : 1) : 0; - // reliable or not - if (!cache.isReliableLatLon()) { - insets.add(INSET_RELIABLE[resolution]); - layers.add(getResources().getDrawable(R.drawable.marker_notreliable)); - } - // cache type - layers.add(getResources().getDrawable(cache.getType().markerId)); - insets.add(INSET_TYPE[resolution]); - // own - if (cache.isOwner()) { - layers.add(getResources().getDrawable(R.drawable.marker_own)); - insets.add(INSET_OWN[resolution]); - // if not, checked if stored - } else if (cache.getListId() > 0) { - layers.add(getResources().getDrawable(R.drawable.marker_stored)); - insets.add(INSET_OWN[resolution]); - } - // found - if (cache.isFound()) { - layers.add(getResources().getDrawable(R.drawable.marker_found)); - insets.add(INSET_FOUND[resolution]); - // if not, perhaps logged offline - } else if (cache.isLogOffline()) { - layers.add(getResources().getDrawable(R.drawable.marker_found_offline)); - insets.add(INSET_FOUND[resolution]); - } - // user modified coords - if (cache.hasUserModifiedCoords()) { - layers.add(getResources().getDrawable(R.drawable.marker_usermodifiedcoords)); - insets.add(INSET_USERMODIFIEDCOORDS[resolution]); - } - // personal note - if (cache.getPersonalNote() != null) { - layers.add(getResources().getDrawable(R.drawable.marker_personalnote)); - insets.add(INSET_PERSONALNOTE[resolution]); - } - - final LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()])); - - int index = 1; - for (final int[] inset : insets) { - ld.setLayerInset(index++, inset[0], inset[1], inset[2], inset[3]); - } - - overlaysCache.put(hashcode, ld); - return ld; - } - private CachesOverlayItemImpl getWaypointItem(final Waypoint waypoint) { final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(waypoint, waypoint.getWaypointType().applyDistanceRule()); final Drawable marker = getResources().getDrawable(!waypoint.isVisited() ? R.drawable.marker : R.drawable.marker_transparent); diff --git a/main/src/cgeo/geocaching/utils/MapUtils.java b/main/src/cgeo/geocaching/utils/MapUtils.java new file mode 100644 index 0000000..948df77 --- /dev/null +++ b/main/src/cgeo/geocaching/utils/MapUtils.java @@ -0,0 +1,126 @@ +package cgeo.geocaching.utils; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; + +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.util.SparseArray; + +import java.util.ArrayList; + +public final class MapUtils { + + // data for overlays + private static final int[][] INSET_RELIABLE = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; // center, 33x40 / 45x51 / 60x68 + private static final int[][] INSET_TYPE = { { 5, 8, 6, 10 }, { 4, 4, 5, 11 }, { 4, 4, 5, 11 } }; // center, 22x22 / 36x36 + private static final int[][] INSET_OWN = { { 21, 0, 0, 26 }, { 25, 0, 0, 35 }, { 40, 0, 0, 48 } }; // top right, 12x12 / 16x16 / 20x20 + private static final int[][] INSET_FOUND = { { 0, 0, 21, 28 }, { 0, 0, 25, 35 }, { 0, 0, 40, 48 } }; // top left, 12x12 / 16x16 / 20x20 + private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 }, { 25, 33, 0, 0 } }; // bottom right, 12x12 / 26x26 / 35x35 + private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 }, { 0, 33, 25, 0 } }; // bottom left, 12x12 / 26x26 / 35x35 + + private static final SparseArray<LayerDrawable> overlaysCache = new SparseArray<>(); + + private MapUtils() { + // Do not instantiate + } + + /** + * Build the drawable for a given cache. + * + * @param res the resources to use + * @param cache the cache to build the drawable for + * @return a drawable representing the current cache status + */ + public static LayerDrawable getCacheItem(final Resources res, final Geocache cache) { + final int hashcode = new HashCodeBuilder() + .append(cache.isReliableLatLon()) + .append(cache.getType().id) + .append(cache.isDisabled() || cache.isArchived()) + .append(cache.getMapMarkerId()) + .append(cache.isOwner()) + .append(cache.isFound()) + .append(cache.hasUserModifiedCoords()) + .append(cache.getPersonalNote()) + .append(cache.isLogOffline()) + .append(cache.getListId() > 0) + .toHashCode(); + + synchronized (overlaysCache) { + LayerDrawable drawable = overlaysCache.get(hashcode); + if (drawable == null) { + drawable = MapUtils.createCacheItem(res, cache); + overlaysCache.put(hashcode, drawable); + } + return drawable; + } + } + + /** + * Clear the cache of drawable items. + */ + public static void clearCachedItems() { + synchronized (overlaysCache) { + overlaysCache.clear(); + } + } + + private static LayerDrawable createCacheItem(final Resources res, final Geocache cache) { + // Set initial capacities to the maximum of layers and insets to avoid dynamic reallocation + final ArrayList<Drawable> layers = new ArrayList<>(9); + final ArrayList<int[]> insets = new ArrayList<>(8); + + // background: disabled or not + final Drawable marker = res.getDrawable(cache.getMapMarkerId()); + layers.add(marker); + final int resolution = marker.getIntrinsicWidth() > 40 ? (marker.getIntrinsicWidth() > 50 ? 2 : 1) : 0; + // reliable or not + if (!cache.isReliableLatLon()) { + insets.add(INSET_RELIABLE[resolution]); + layers.add(res.getDrawable(R.drawable.marker_notreliable)); + } + // cache type + layers.add(res.getDrawable(cache.getType().markerId)); + insets.add(INSET_TYPE[resolution]); + // own + if (cache.isOwner()) { + layers.add(res.getDrawable(R.drawable.marker_own)); + insets.add(INSET_OWN[resolution]); + // if not, checked if stored + } else if (cache.getListId() > 0) { + layers.add(res.getDrawable(R.drawable.marker_stored)); + insets.add(INSET_OWN[resolution]); + } + // found + if (cache.isFound()) { + layers.add(res.getDrawable(R.drawable.marker_found)); + insets.add(INSET_FOUND[resolution]); + // if not, perhaps logged offline + } else if (cache.isLogOffline()) { + layers.add(res.getDrawable(R.drawable.marker_found_offline)); + insets.add(INSET_FOUND[resolution]); + } + // user modified coords + if (cache.hasUserModifiedCoords()) { + layers.add(res.getDrawable(R.drawable.marker_usermodifiedcoords)); + insets.add(INSET_USERMODIFIEDCOORDS[resolution]); + } + // personal note + if (cache.getPersonalNote() != null) { + layers.add(res.getDrawable(R.drawable.marker_personalnote)); + insets.add(INSET_PERSONALNOTE[resolution]); + } + + final LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()])); + + int index = 1; + for (final int[] inset : insets) { + ld.setLayerInset(index++, inset[0], inset[1], inset[2], inset[3]); + } + + return ld; + } +} |
