forked from upstream-mirrors/OpenTracks
Implemented MarkerIterator.
This commit is contained in:
@@ -7,6 +7,7 @@ import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
|||||||
/**
|
/**
|
||||||
* A cache of track points indexes.
|
* A cache of track points indexes.
|
||||||
*/
|
*/
|
||||||
|
//TOOD Check if this actually useful.
|
||||||
class CachedTrackPointsIndexes {
|
class CachedTrackPointsIndexes {
|
||||||
final int idIndex;
|
final int idIndex;
|
||||||
final int typeIndex;
|
final int typeIndex;
|
||||||
|
|||||||
@@ -430,6 +430,11 @@ public class ContentProviderUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AutoCloseableIterator<Marker> getMarkerIterator(@NonNull Track.Id trackId) {
|
||||||
|
return new MarkerIterator(this, trackId, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Use MarkerIterator instead
|
||||||
public Cursor getMarkerCursor(@NonNull Track.Id trackId) {
|
public Cursor getMarkerCursor(@NonNull Track.Id trackId) {
|
||||||
return getMarkerCursor(trackId, -1);
|
return getMarkerCursor(trackId, -1);
|
||||||
}
|
}
|
||||||
@@ -731,7 +736,7 @@ public class ContentProviderUtils {
|
|||||||
* @param trackId the track id
|
* @param trackId the track id
|
||||||
* @param startTrackPointId the starting trackPoint id. `null` to ignore
|
* @param startTrackPointId the starting trackPoint id. `null` to ignore
|
||||||
*/
|
*/
|
||||||
public AutoCloseableIterator<TrackPoint> getTrackPointIterator(final Track.Id trackId, final TrackPoint.Id startTrackPointId) {
|
public AutoCloseableIterator<TrackPoint> getTrackPointIterator(Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
||||||
return new TrackPointIterator(this, trackId, startTrackPointId);
|
return new TrackPointIterator(this, trackId, startTrackPointId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package de.dennisguse.opentracks.data;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.data.models.Marker;
|
||||||
|
import de.dennisguse.opentracks.data.models.Track;
|
||||||
|
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||||
|
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||||
|
|
||||||
|
class MarkerIterator extends AutoCloseableIterator<Marker> {
|
||||||
|
|
||||||
|
private static final String TAG = MarkerIterator.class.getSimpleName();
|
||||||
|
|
||||||
|
private final ContentProviderUtils contentProviderUtils;
|
||||||
|
private Cursor cursor;
|
||||||
|
|
||||||
|
MarkerIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, int maxCount) {
|
||||||
|
this.contentProviderUtils = contentProviderUtils;
|
||||||
|
|
||||||
|
cursor = contentProviderUtils.getMarkerCursor(trackId, maxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (cursor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !cursor.isLast() && !cursor.isAfterLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Marker next() {
|
||||||
|
if (cursor == null || !cursor.moveToNext()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
return contentProviderUtils.createMarker(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPosition() {
|
||||||
|
return cursor.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public int getCount() {
|
||||||
|
return cursor.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
cursor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,16 +17,10 @@ import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
|||||||
class TrackPointIterator extends AutoCloseableIterator<TrackPoint> {
|
class TrackPointIterator extends AutoCloseableIterator<TrackPoint> {
|
||||||
|
|
||||||
private static final String TAG = TrackPointIterator.class.getSimpleName();
|
private static final String TAG = TrackPointIterator.class.getSimpleName();
|
||||||
|
|
||||||
private final ContentProviderUtils contentProviderUtils;
|
|
||||||
private final Track.Id trackId;
|
|
||||||
private final CachedTrackPointsIndexes indexes;
|
private final CachedTrackPointsIndexes indexes;
|
||||||
private Cursor cursor;
|
private Cursor cursor;
|
||||||
|
|
||||||
TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
||||||
this.contentProviderUtils = contentProviderUtils;
|
|
||||||
this.trackId = trackId;
|
|
||||||
|
|
||||||
cursor = contentProviderUtils.getTrackPointCursor(trackId, startTrackPointId);
|
cursor = contentProviderUtils.getTrackPointCursor(trackId, startTrackPointId);
|
||||||
indexes = new CachedTrackPointsIndexes(cursor);
|
indexes = new CachedTrackPointsIndexes(cursor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,17 +238,12 @@ public class GPXTrackExporter implements TrackExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeMarkers(Track track) throws InterruptedException {
|
private void writeMarkers(Track track) throws InterruptedException {
|
||||||
try (Cursor cursor = contentProviderUtils.getMarkerCursor(track.getId())) {
|
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.getId())) {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
while (markerIterator.hasNext()) {
|
||||||
for (int i = 0; i < cursor.getCount(); i++) {
|
if (Thread.interrupted()) throw new InterruptedException();
|
||||||
if (Thread.interrupted()) {
|
|
||||||
throw new InterruptedException();
|
|
||||||
}
|
|
||||||
Marker marker = contentProviderUtils.createMarker(cursor);
|
|
||||||
writeMarker(track.getZoneOffset(), marker);
|
|
||||||
|
|
||||||
cursor.moveToNext();
|
|
||||||
}
|
writeMarker(track.getZoneOffset(), markerIterator.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,21 +136,16 @@ public class KMLTrackExporter implements TrackExporter {
|
|||||||
|
|
||||||
private void writeMarkers(Track track) throws InterruptedException {
|
private void writeMarkers(Track track) throws InterruptedException {
|
||||||
boolean hasMarkers = false;
|
boolean hasMarkers = false;
|
||||||
try (Cursor cursor = contentProviderUtils.getMarkerCursor(track.getId())) {
|
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.getId())) {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
while (markerIterator.hasNext()) {
|
||||||
for (int i = 0; i < cursor.getCount(); i++) {
|
if (Thread.interrupted()) throw new InterruptedException();
|
||||||
if (Thread.interrupted()) {
|
|
||||||
throw new InterruptedException();
|
|
||||||
}
|
|
||||||
if (!hasMarkers) {
|
|
||||||
writeBeginMarkers(track);
|
|
||||||
hasMarkers = true;
|
|
||||||
}
|
|
||||||
Marker marker = contentProviderUtils.createMarker(cursor);
|
|
||||||
writeMarker(marker, track.getZoneOffset());
|
|
||||||
|
|
||||||
cursor.moveToNext();
|
if (!hasMarkers) {
|
||||||
|
writeBeginMarkers(track);
|
||||||
|
hasMarkers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeMarker(markerIterator.next(), track.getZoneOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasMarkers) {
|
if (hasMarkers) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import de.dennisguse.opentracks.data.ContentProviderUtils;
|
|||||||
import de.dennisguse.opentracks.data.models.Marker;
|
import de.dennisguse.opentracks.data.models.Marker;
|
||||||
import de.dennisguse.opentracks.data.models.Track;
|
import de.dennisguse.opentracks.data.models.Track;
|
||||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||||
|
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||||
import de.dennisguse.opentracks.util.FileUtils;
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,22 +90,17 @@ public class KMZTrackExporter implements TrackExporter {
|
|||||||
|
|
||||||
private void addImages(Context context, List<Track> tracks, ZipOutputStream zipOutputStream) throws InterruptedException, IOException {
|
private void addImages(Context context, List<Track> tracks, ZipOutputStream zipOutputStream) throws InterruptedException, IOException {
|
||||||
for (Track track : tracks) {
|
for (Track track : tracks) {
|
||||||
try (Cursor cursor = contentProviderUtils.getMarkerCursor(track.getId())) {
|
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.getId())) {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
while (markerIterator.hasNext()) {
|
||||||
for (int i = 0; i < cursor.getCount(); i++) {
|
if (Thread.interrupted()) throw new InterruptedException();
|
||||||
if (Thread.interrupted()) {
|
|
||||||
throw new InterruptedException();
|
|
||||||
}
|
|
||||||
Marker marker = contentProviderUtils.createMarker(cursor);
|
|
||||||
if (marker.hasPhoto()) {
|
|
||||||
Uri uriPhoto = marker.getPhotoUrl();
|
|
||||||
boolean existsPhoto = MarkerUtils.buildInternalPhotoFile(context, track.getId(), uriPhoto) != null;
|
|
||||||
if (existsPhoto) {
|
|
||||||
addImage(context, zipOutputStream, uriPhoto, marker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.moveToNext();
|
Marker marker = markerIterator.next();
|
||||||
|
if (marker.hasPhoto()) {
|
||||||
|
Uri uriPhoto = marker.getPhotoUrl();
|
||||||
|
boolean existsPhoto = MarkerUtils.buildInternalPhotoFile(context, track.getId(), uriPhoto) != null;
|
||||||
|
if (existsPhoto) {
|
||||||
|
addImage(context, zipOutputStream, uriPhoto, marker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ import de.dennisguse.opentracks.R;
|
|||||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||||
import de.dennisguse.opentracks.data.models.Marker;
|
import de.dennisguse.opentracks.data.models.Marker;
|
||||||
import de.dennisguse.opentracks.data.models.Track;
|
import de.dennisguse.opentracks.data.models.Track;
|
||||||
|
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||||
import de.dennisguse.opentracks.util.FileUtils;
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,13 +190,14 @@ public class KMZTrackImporter {
|
|||||||
private void deleteOrphanImages(Track.Id trackId) {
|
private void deleteOrphanImages(Track.Id trackId) {
|
||||||
// 1.- Gets all photo names in the markers of the track identified by id.
|
// 1.- Gets all photo names in the markers of the track identified by id.
|
||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||||
List<Marker> markers = contentProviderUtils.getMarkers(trackId);
|
|
||||||
List<String> photosName = new ArrayList<>();
|
List<String> photosName = new ArrayList<>();
|
||||||
for (Marker marker : markers) {
|
try (AutoCloseableIterator<Marker> markerIterator = new ContentProviderUtils(context).getMarkerIterator(trackId)) {
|
||||||
if (marker.hasPhoto()) {
|
markerIterator.forEachRemaining(marker -> {
|
||||||
String photoUrl = Uri.decode(marker.getPhotoUrl().toString()); //TODO Why Uri.decode()?
|
if (marker.hasPhoto()) {
|
||||||
photosName.add(photoUrl.substring(photoUrl.lastIndexOf(File.separatorChar) + 1));
|
String photoUrl = Uri.decode(marker.getPhotoUrl().toString()); //TODO Why Uri.decode()?
|
||||||
}
|
photosName.add(photoUrl.substring(photoUrl.lastIndexOf(File.separatorChar) + 1));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.- Deletes all orphan photos from external storage.
|
// 2.- Deletes all orphan photos from external storage.
|
||||||
|
|||||||
Reference in New Issue
Block a user