diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index 63daababa7..f250942298 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -112,16 +112,11 @@ public class FavouritesDbHelper { } public void delete(Set groupsToDelete, Set favoritesSelected) { - MapMarkersHelper markersHelper = context.getMapMarkersHelper(); if (favoritesSelected != null) { for (FavouritePoint p : favoritesSelected) { FavoriteGroup group = flatGroups.get(p.getCategory()); if (group != null) { group.points.remove(p); - long groupId = markersHelper.getGroupId(group.name); - if (groupId != -1) { - markersHelper.removeMarker(p.getLatitude(), p.getLongitude(), groupId); - } } cachedFavoritePoints.remove(p); } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index fdc1edde1d..b51e67e727 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -17,14 +17,15 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.LinkedList; import java.util.List; import java.util.Locale; public class MapMarkersHelper { public static final int MAP_MARKERS_COLORS_COUNT = 7; - private List mapMarkers = new ArrayList<>(); - private List mapMarkersHistory = new ArrayList<>(); + private List mapMarkers = new LinkedList<>(); + private List mapMarkersHistory = new LinkedList<>(); private OsmandSettings settings; private List listeners = new ArrayList<>(); private OsmandApplication ctx; @@ -38,7 +39,7 @@ public class MapMarkersHelper { } public static class MapMarker implements LocationPoint { - public long id; + public String id; public LatLon point; private PointDescription pointDescription; public int colorIndex; @@ -48,8 +49,9 @@ public class MapMarkersHelper { public int dist; public long creationDate; public long visitedDate; - public long nextKey; + public String nextKey; public long groupKey = -1; + public String groupName; public MapMarker(LatLon point, PointDescription name, int colorIndex, boolean selected, int index) { @@ -194,6 +196,26 @@ public class MapMarkersHelper { } } + public void checkAndFixActiveMarkersOrderIfNeeded() { + if (!mapMarkers.isEmpty()) { + if (mapMarkers.size() > 1) { + for (int i = 0; i < mapMarkers.size() - 1; i++) { + MapMarker first = mapMarkers.get(i); + MapMarker second = mapMarkers.get(i + 1); + if (!first.nextKey.equals(second.id)) { + markersDbHelper.changeActiveMarkerPosition(first, second); + first.nextKey = second.id; + } + } + } + + MapMarker tail = mapMarkers.get(mapMarkers.size() - 1); + if (!tail.nextKey.equals(MapMarkersDbHelper.TAIL_NEXT_VALUE)) { + markersDbHelper.changeActiveMarkerPosition(tail, null); + } + } + } + private void sortMarkers(List markers, final boolean history) { Collections.sort(markers, new Comparator() { @Override @@ -214,18 +236,19 @@ public class MapMarkersHelper { private void lookupAddress(final MapMarker mapMarker) { if (mapMarker != null && mapMarker.pointDescription.isSearchingAddress(ctx)) { cancelPointAddressRequests(mapMarker.point); - GeocodingLookupService.AddressLookupRequest lookupRequest = new GeocodingLookupService.AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() { - @Override - public void geocodingDone(String address) { - if (Algorithms.isEmpty(address)) { - mapMarker.pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx)); - } else { - mapMarker.pointDescription.setName(address); - } - markersDbHelper.updateMarker(mapMarker); - updateMarker(mapMarker); - } - }, null); + GeocodingLookupService.AddressLookupRequest lookupRequest = + new GeocodingLookupService.AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() { + @Override + public void geocodingDone(String address) { + if (Algorithms.isEmpty(address)) { + mapMarker.pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx)); + } else { + mapMarker.pointDescription.setName(address); + } + markersDbHelper.updateMarker(mapMarker); + updateMarker(mapMarker); + } + }, null); ctx.getGeocodingLookupService().lookupAddress(lookupRequest); } } @@ -234,11 +257,11 @@ public class MapMarkersHelper { return markersDbHelper.getGroupId(name); } - public void removeMarker(double lat, double lon, long groupId) { - markersDbHelper.removeMarker(lat, lon, groupId); - loadMarkers(); - refresh(); - } +// public void removeMarker(double lat, double lon, long groupId) { +// markersDbHelper.removeMarker(lat, lon, groupId); +// loadMarkers(); +// refresh(); +// } @Nullable public String getGroupName(long id) { @@ -249,17 +272,24 @@ public class MapMarkersHelper { if (marker != null) { cancelPointAddressRequests(marker.point); markersDbHelper.moveMarkerToHistory(marker); - loadMarkers(); + mapMarkers.remove(marker); + marker.history = true; + marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE; + mapMarkersHistory.add(marker); + checkAndFixActiveMarkersOrderIfNeeded(); + sortMarkers(mapMarkersHistory, true); refresh(); } } public void restoreMarkerFromHistory(MapMarker marker, int position) { if (marker != null) { - MapMarker next = position == mapMarkers.size() ? null : mapMarkers.get(position); markersDbHelper.restoreMapMarkerFromHistory(marker); - markersDbHelper.changeActiveMarkerPosition(marker, next); - loadMarkers(); + mapMarkersHistory.remove(marker); + marker.history = false; + mapMarkers.add(position, marker); + checkAndFixActiveMarkersOrderIfNeeded(); + sortMarkers(mapMarkersHistory, true); refresh(); } } @@ -267,7 +297,7 @@ public class MapMarkersHelper { public void removeMarkerFromHistory(MapMarker marker) { if (marker != null) { markersDbHelper.removeMarkerFromHistory(marker); - loadMarkers(); + mapMarkersHistory.remove(marker); refresh(); } } @@ -326,17 +356,20 @@ public class MapMarkersHelper { public void reverseActiveMarkersOrder() { cancelAddressRequests(); - - markersDbHelper.reverseActiveMarkersOrder(); - loadMarkers(); + Collections.reverse(mapMarkers); + checkAndFixActiveMarkersOrderIfNeeded(); } - public void removeActiveMarkers() { + public void moveAllActiveMarkersToHistory() { cancelAddressRequests(); markersDbHelper.moveAllActiveMarkersToHistory(); + for (MapMarker marker : mapMarkers) { + marker.history = true; + marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE; + } + mapMarkersHistory.addAll(mapMarkers); mapMarkers.clear(); - mapMarkersHistory.clear(); - mapMarkersHistory.addAll(markersDbHelper.getMarkersHistory()); + sortMarkers(mapMarkersHistory, true); refresh(); } @@ -388,9 +421,12 @@ public class MapMarkersHelper { if (groups != null) { marker.groupKey = markersDbHelper.createGroupIfNeeded(groups.get(i)); } + marker.history = false; + marker.nextKey = MapMarkersDbHelper.TAIL_NEXT_VALUE; markersDbHelper.addMarker(marker); + mapMarkers.add(marker); + checkAndFixActiveMarkersOrderIfNeeded(); } - loadMarkers(); } } @@ -406,26 +442,24 @@ public class MapMarkersHelper { public void moveMapMarker(@Nullable MapMarker marker, LatLon latLon) { if (marker != null) { - marker.point = new LatLon(latLon.getLatitude(), latLon.getLongitude()); + LatLon point = new LatLon(latLon.getLatitude(), latLon.getLongitude()); + int index = mapMarkers.indexOf(marker); + if (index != -1) { + mapMarkers.get(index).point = point; + } + marker.point = point; markersDbHelper.updateMarker(marker); - loadMarkers(); + checkAndFixActiveMarkersOrderIfNeeded(); refresh(); } } - public void changeActiveMarkerPositionInDb(int currentPosInMapMarkers) { - MapMarker moved = mapMarkers.get(currentPosInMapMarkers); - markersDbHelper.changeActiveMarkerPosition(moved, - currentPosInMapMarkers == mapMarkers.size() - 1 ? null : mapMarkers.get(currentPosInMapMarkers + 1)); - loadMarkers(); - } - public void moveMarkerToTop(MapMarker marker) { int i = mapMarkers.indexOf(marker); if (i != -1 && mapMarkers.size() > 1) { mapMarkers.remove(i); - markersDbHelper.changeActiveMarkerPosition(marker, mapMarkers.get(0)); - loadMarkers(); + mapMarkers.add(0, marker); + checkAndFixActiveMarkersOrderIfNeeded(); refresh(); } } diff --git a/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java b/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java index 35823dfcba..4b88b2089b 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java @@ -354,7 +354,7 @@ public class MapMarkerDialogHelper { @Override public void onClick(DialogInterface dialog, int which) { listAdapter.notifyDataSetInvalidated(); - markersHelper.removeActiveMarkers(); + markersHelper.moveAllActiveMarkersToHistory(); if (markersHelper.getMapMarkersHistory().size() == 0) { mapActivity.getDashboard().hideDashboard(); } else if (helperCallbacks != null) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java index 0472875d9e..cde730ea9c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java @@ -68,7 +68,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL toPosition = holder.getAdapterPosition(); if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) { hideSnackbar(); - mapActivity.getMyApplication().getMapMarkersHelper().changeActiveMarkerPositionInDb(toPosition); + mapActivity.getMyApplication().getMapMarkersHelper().checkAndFixActiveMarkersOrderIfNeeded(); } } }); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java index 4be7f32a70..0e6714b1b5 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java @@ -1,7 +1,6 @@ package net.osmand.plus.mapmarkers; import android.support.annotation.Nullable; -import android.support.v4.util.LongSparseArray; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; @@ -13,39 +12,43 @@ import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.helpers.SearchHistoryHelper; import java.util.Calendar; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Random; public class MapMarkersDbHelper { - private static final int DB_VERSION = 3; + private static final int DB_VERSION = 4; public static final String DB_NAME = "map_markers_db"; private static final String MARKERS_TABLE_NAME = "map_markers"; private static final String MARKERS_COL_ID = "marker_id"; - private static final String MARKERS_COL_LAT = "marker_latitude"; - private static final String MARKERS_COL_LON = "marker_longitude"; + private static final String MARKERS_COL_LAT = "marker_lat"; + private static final String MARKERS_COL_LON = "marker_lon"; private static final String MARKERS_COL_DESCRIPTION = "marker_description"; private static final String MARKERS_COL_ACTIVE = "marker_active"; private static final String MARKERS_COL_ADDED = "marker_added"; private static final String MARKERS_COL_VISITED = "marker_visited"; + private static final String MARKERS_COL_GROUP_NAME = "group_name"; private static final String MARKERS_COL_GROUP_KEY = "group_key"; private static final String MARKERS_COL_COLOR = "marker_color"; private static final String MARKERS_COL_NEXT_KEY = "marker_next_key"; private static final String MARKERS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + MARKERS_TABLE_NAME + " (" + - MARKERS_COL_ID + " long PRIMARY KEY, " + + MARKERS_COL_ID + " TEXT PRIMARY KEY, " + MARKERS_COL_LAT + " double, " + MARKERS_COL_LON + " double, " + MARKERS_COL_DESCRIPTION + " TEXT, " + MARKERS_COL_ACTIVE + " int, " + // 1 = true, 0 = false MARKERS_COL_ADDED + " long, " + MARKERS_COL_VISITED + " long, " + + MARKERS_COL_GROUP_NAME + " TEXT, " + MARKERS_COL_GROUP_KEY + " long, " + MARKERS_COL_COLOR + " int, " + - MARKERS_COL_NEXT_KEY + " long);"; + MARKERS_COL_NEXT_KEY + " TEXT);"; private static final String MARKERS_TABLE_SELECT = "SELECT " + MARKERS_COL_ID + ", " + @@ -55,6 +58,7 @@ public class MapMarkersDbHelper { MARKERS_COL_ACTIVE + ", " + MARKERS_COL_ADDED + ", " + MARKERS_COL_VISITED + ", " + + MARKERS_COL_GROUP_NAME + ", " + MARKERS_COL_GROUP_KEY + ", " + MARKERS_COL_COLOR + ", " + MARKERS_COL_NEXT_KEY + @@ -74,8 +78,8 @@ public class MapMarkersDbHelper { GROUPS_COL_NAME + " FROM " + GROUPS_TABLE_NAME; - private static final int TAIL_NEXT_VALUE = 0; - private static final int HISTORY_NEXT_VALUE = -1; + public static final String TAIL_NEXT_VALUE = "tail_next"; + public static final String HISTORY_NEXT_VALUE = "history_next"; private final OsmandApplication context; @@ -145,14 +149,6 @@ public class MapMarkersDbHelper { } } - public void reverseActiveMarkersOrder() { - List markers = getActiveMarkers(); - removeAllActiveMarkers(); - for (int i = markers.size() - 1; i >= 0; i--) { - addMarker(markers.get(i)); - } - } - public long createGroupIfNeeded(String name) { long res = -1; SQLiteConnection db = openConnection(false); @@ -198,15 +194,11 @@ public class MapMarkersDbHelper { } else { currentTime = System.currentTimeMillis(); } - marker.id = Long.parseLong(String.valueOf(currentTime) + String.valueOf(new Random().nextInt(900) + 100)); + marker.id = String.valueOf(currentTime) + String.valueOf(new Random().nextInt(900) + 100); marker.creationDate = currentTime; - double lat = marker.getLatitude(); - double lon = marker.getLongitude(); String descr = PointDescription.serializeToString(marker.getOriginalPointDescription()); int active = marker.history ? 0 : 1; long visited = saveExisting ? currentTime : 0; - long groupKey = marker.groupKey; - int colorIndex = marker.colorIndex; PointDescription pointDescription = marker.getOriginalPointDescription(); if (pointDescription != null && !pointDescription.isSearchingAddress(context)) { @@ -219,8 +211,9 @@ public class MapMarkersDbHelper { "WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{marker.id, TAIL_NEXT_VALUE}); } - db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - new Object[]{marker.id, lat, lon, descr, active, currentTime, visited, groupKey, colorIndex, + db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + new Object[]{marker.id, marker.getLatitude(), marker.getLongitude(), descr, active, + currentTime, visited, marker.groupName, marker.groupKey, marker.colorIndex, marker.history ? HISTORY_NEXT_VALUE : TAIL_NEXT_VALUE}); } @@ -265,7 +258,7 @@ public class MapMarkersDbHelper { public List getActiveMarkers() { List res = new LinkedList<>(); - LongSparseArray markers = new LongSparseArray<>(); + HashMap markers = new LinkedHashMap<>(); SQLiteConnection db = openConnection(true); if (db != null) { try { @@ -274,29 +267,30 @@ public class MapMarkersDbHelper { if (query.moveToFirst()) { do { MapMarker marker = readItem(query); - markers.put(marker.nextKey, marker); + markers.put(marker.id, marker); } while (query.moveToNext()); } query.close(); } finally { db.close(); } - buildLinkedList(markers, res, markers.get(TAIL_NEXT_VALUE)); + buildLinkedList(markers, res); } return res; } private MapMarker readItem(SQLiteCursor query) { - long id = query.getLong(0); + String id = query.getString(0); double lat = query.getDouble(1); double lon = query.getDouble(2); String desc = query.getString(3); boolean active = query.getInt(4) == 1; long added = query.getLong(5); long visited = query.getLong(6); - long groupKey = query.getLong(7); - int colorIndex = query.getInt(8); - long nextKey = query.getLong(9); + String groupName = query.getString(7); + long groupKey = query.getLong(8); + int colorIndex = query.getInt(9); + String nextKey = query.getString(10); LatLon latLon = new LatLon(lat, lon); MapMarker marker = new MapMarker(latLon, PointDescription.deserializeFromString(desc, latLon), @@ -305,19 +299,23 @@ public class MapMarkersDbHelper { marker.history = !active; marker.creationDate = added; marker.visitedDate = visited; + marker.groupName = groupName; marker.groupKey = groupKey; marker.nextKey = nextKey; return marker; } - private void buildLinkedList(LongSparseArray markers, List res, MapMarker marker) { - if (marker != null) { - res.add(0, marker); - MapMarker prev = markers.get(marker.id); - if (prev != null) { - buildLinkedList(markers, res, prev); + private void buildLinkedList(HashMap markers, List res) { + if (!markers.isEmpty()) { + for (MapMarker marker : markers.values()) { + if (!markers.keySet().contains(marker.nextKey)) { + res.add(0, marker); + markers.remove(marker.id); + break; + } } + buildLinkedList(markers, res); } } @@ -343,12 +341,6 @@ public class MapMarkersDbHelper { SQLiteConnection db = openConnection(false); if (db != null) { try { - db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " + - "WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{moved.nextKey, moved.id}); - - db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " + - "WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{moved.id, next == null ? TAIL_NEXT_VALUE : next.id}); - db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " + "WHERE " + MARKERS_COL_ID + " = ?", new Object[]{next == null ? TAIL_NEXT_VALUE : next.id, moved.id}); } finally { @@ -357,18 +349,6 @@ public class MapMarkersDbHelper { } } - private void removeAllActiveMarkers() { - SQLiteConnection db = openConnection(true); - if (db != null) { - try { - db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME + " WHERE " + MARKERS_COL_ACTIVE + " = ?", - new Object[]{1}); - } finally { - db.close(); - } - } - } - public void removeMarker(double lat, double lon, long groupId) { SQLiteConnection db = openConnection(false); if (db != null) { @@ -407,13 +387,11 @@ public class MapMarkersDbHelper { try { marker.visitedDate = System.currentTimeMillis(); - db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " + - "WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{marker.nextKey, marker.id}); - db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_ACTIVE + " = ?, " + - MARKERS_COL_VISITED + " = ? " + - "WHERE " + MARKERS_COL_ID + " = ?", new Object[]{0, marker.visitedDate, marker.id}); + MARKERS_COL_VISITED + " = ?, " + + MARKERS_COL_NEXT_KEY + " = ? " + + "WHERE " + MARKERS_COL_ID + " = ?", new Object[]{0, marker.visitedDate, HISTORY_NEXT_VALUE, marker.id}); } finally { db.close(); } @@ -427,8 +405,9 @@ public class MapMarkersDbHelper { long visitedDate = System.currentTimeMillis(); db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_ACTIVE + " = ?, " + - MARKERS_COL_VISITED + " = ? " + - "WHERE " + MARKERS_COL_ACTIVE + " = ?", new Object[]{0, visitedDate, 1}); + MARKERS_COL_VISITED + " = ?, " + + MARKERS_COL_NEXT_KEY + " = ? " + + "WHERE " + MARKERS_COL_ACTIVE + " = ?", new Object[]{0, visitedDate, HISTORY_NEXT_VALUE, 1}); } finally { db.close(); } @@ -439,13 +418,11 @@ public class MapMarkersDbHelper { SQLiteConnection db = openConnection(false); if (db != null) { try { - List active = getActiveMarkers(); db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + - MARKERS_COL_ACTIVE + " = ?, " + - MARKERS_COL_NEXT_KEY + " = ? " + + MARKERS_COL_ACTIVE + " = ? " + "WHERE " + MARKERS_COL_ID + " = ? " + "AND " + MARKERS_COL_ACTIVE + " = ?", - new Object[]{1, active.size() > 0 ? active.get(0).id : TAIL_NEXT_VALUE, marker.id, 0}); + new Object[]{1, marker.id, 0}); } finally { db.close(); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java index 4e30eb5f65..cf570549c9 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java @@ -161,7 +161,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm @Override public void moveAllToHistoryOnClick() { - mapActivity.getMyApplication().getMapMarkersHelper().removeActiveMarkers(); + mapActivity.getMyApplication().getMapMarkersHelper().moveAllActiveMarkersToHistory(); activeFragment.updateAdapter(); } };