diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index 048d04a84..bf6264345 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -838,6 +838,18 @@ JNIEXPORT jint Java_com_b44t_messenger_DcArray_getLocationId(JNIEnv *env, jobjec } +JNIEXPORT jstring Java_com_b44t_messenger_DcArray_getMarker(JNIEnv *env, jobject obj, jint index) +{ + char* temp = dc_array_get_marker(get_dc_array(env, obj), index); + jstring ret = NULL; + if (temp) { + ret = JSTRING_NEW(temp); + } + free(temp); + return ret; +} + + /******************************************************************************* * DcChatlist ******************************************************************************/ diff --git a/res/drawable-hdpi/ic_location_on_white_48dp.png b/res/drawable-hdpi/ic_location_on_white_48dp.png new file mode 100755 index 000000000..d226e78f1 Binary files /dev/null and b/res/drawable-hdpi/ic_location_on_white_48dp.png differ diff --git a/res/layout/bottom_map_sheet.xml b/res/layout/bottom_map_sheet.xml index 038c28804..39ee176bc 100644 --- a/res/layout/bottom_map_sheet.xml +++ b/res/layout/bottom_map_sheet.xml @@ -62,6 +62,8 @@ android:paddingRight="40dp" android:layout_width="match_parent" android:layout_height="120dp" + app:minValue="50" + app:maxValue="100" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index acc5aedee..61f5d29eb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -221,7 +221,6 @@ Show locations in time frame - Last position Show traces diff --git a/src/com/b44t/messenger/DcArray.java b/src/com/b44t/messenger/DcArray.java index dd255ee16..05580574f 100644 --- a/src/com/b44t/messenger/DcArray.java +++ b/src/com/b44t/messenger/DcArray.java @@ -19,6 +19,7 @@ public class DcArray { public native long getTimestamp (int index); public native int getMsgId (int index); public native int getLocationId(int index); + public native String getMarker (int index); // working with raw c-data private long arrayCPtr; // CAVE: the name is referenced in the JNI diff --git a/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java b/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java index c95d5445a..a99d94951 100644 --- a/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java +++ b/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java @@ -211,6 +211,9 @@ public class RangeSliderView extends View { longPressDetector.onTouchEvent(event); if (event.getAction() == MotionEvent.ACTION_CANCEL) { + if (onValueChangedListener != null) { + onValueChangedListener.onValueChanged(minValue, maxValue); + } minValueThumb.isHighlight = false; maxValueThumb.isHighlight = false; isThumbViewLocked = false; diff --git a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java index 68d0fd800..0e9e503f0 100644 --- a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java +++ b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java @@ -18,7 +18,6 @@ import java.util.Locale; public class TimeRangeSlider extends RangeSliderView implements RangeSliderView.OnValueChangedListener { private static final int DEFAULT_TIMEFRAME_2D = 60 * 60 * 24 * 2; // 2d private static final float DEFAULT_DELTA = 1000 * 60 * 30; // 30 min - private static final float LAST_POSITON_DELTA = 1000 * 60 * 60 * 24; //1d int timeFrame; // timeframe in seconds Locale locale; @@ -91,12 +90,6 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. public interface OnTimestampChangedListener { void onTimestampChanged(long startTimestamp, long stopTimestamp); - - /** - * filter for lastPosition beginning from startTimestamp to now - * @param startTimestamp begin of time frame - */ - void onFilterLastPosition(long startTimestamp); } @@ -109,13 +102,8 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. if (listener != null) { long minTimeStamp = getTimestampForValue(minValue); if (minValue == maxValue) { - if (minValue == getCount()) { - // filter last location - listener.onFilterLastPosition(System.currentTimeMillis() - (long) LAST_POSITON_DELTA); - } else { - // filter for time of event with delta before and after - listener.onTimestampChanged(minTimeStamp - (long) DEFAULT_DELTA, minTimeStamp + (long) DEFAULT_DELTA); - } + // filter for time of event with delta before and after + listener.onTimestampChanged(minTimeStamp - (long) DEFAULT_DELTA, minTimeStamp + (long) DEFAULT_DELTA); } else { //filter for time span listener.onTimestampChanged(minTimeStamp, getTimestampForValue(maxValue)); @@ -133,9 +121,6 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. @Override public String parseMaxValueDisplayText(int maxValue) { - if (minValue == maxValue && maxValue == getCount()) { - return getContext().getResources().getString(R.string.filter_last_position); - } return getStringForValue(maxValue); } @@ -157,20 +142,8 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. * @return normalized delta */ private float getDelta() { - if (minValue == getCount()) { - return getLastPositionDelta(); - } else { - return getDefaultDelta(); - } - } - - private float getDefaultDelta() { return DEFAULT_DELTA / (timeFrame * 1000) * getCount(); } - private float getLastPositionDelta() { - return LAST_POSITON_DELTA / (timeFrame * 1000) * getCount(); - } - } diff --git a/src/org/thoughtcrime/securesms/map/DataCollectionTask.java b/src/org/thoughtcrime/securesms/map/DataCollectionTask.java new file mode 100644 index 000000000..9b0390d5f --- /dev/null +++ b/src/org/thoughtcrime/securesms/map/DataCollectionTask.java @@ -0,0 +1,114 @@ +package org.thoughtcrime.securesms.map; + +import android.os.AsyncTask; + +import com.b44t.messenger.DcArray; +import com.b44t.messenger.DcContext; +import com.google.gson.JsonObject; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.LineString; +import com.mapbox.geojson.Point; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; + +import org.thoughtcrime.securesms.map.model.MapSource; + +import java.util.ArrayList; +import java.util.HashMap; + +import static org.thoughtcrime.securesms.map.MapDataManager.ACCURACY; +import static org.thoughtcrime.securesms.map.MapDataManager.CONTACT_ID; +import static org.thoughtcrime.securesms.map.MapDataManager.LAST_LOCATION; +import static org.thoughtcrime.securesms.map.MapDataManager.MARKER_SELECTED; +import static org.thoughtcrime.securesms.map.MapDataManager.MESSAGE_ID; +import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; +import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP_NOW; +import static org.thoughtcrime.securesms.map.MapDataManager.TIME_FRAME; + +/** + * Created by cyberta on 15.04.19. + */ + +public class DataCollectionTask extends AsyncTask { + + public class DataCollection { + HashMap> featureCollections; + + public DataCollection(HashMap> featureCollections) { + this.featureCollections = featureCollections; + } + } + + private final int chatId; + private final HashMap contactMapSources; + private final LatLngBounds.Builder boundingBuilder; + private final DcContext dcContext; + + public DataCollectionTask(DcContext context, int chatId, HashMap contactMapSources, LatLngBounds.Builder boundingBuilder) { + this.chatId = chatId; + this.contactMapSources = contactMapSources; + this.boundingBuilder = boundingBuilder; + this.dcContext = context; + } + + @Override + protected DataCollection doInBackground(Void... voids) { + HashMap> featureCollections = new HashMap<>(); + for (int contactId : contactMapSources.keySet()) { + updateSource(chatId, contactId, System.currentTimeMillis() - TIME_FRAME, TIMESTAMP_NOW, featureCollections, boundingBuilder); + } + + return new DataCollection(featureCollections); + } + + private void updateSource(int chatId, int contactId, long startTimestamp, long endTimestamp, HashMap> featureCollections, LatLngBounds.Builder boundingBuilder) { + //long start = System.currentTimeMillis(); + DcArray locations = dcContext.getLocations(chatId, contactId, startTimestamp, endTimestamp); + MapSource contactMapMetadata = contactMapSources.get(contactId); + + ArrayList sortedPointFeatures = new ArrayList<>(); + ArrayList sortedLineFeatures = new ArrayList<>(); + + int count = locations.getCnt(); + for (int i = sortedPointFeatures.size(); i < count; i++) { + Point point = Point.fromLngLat(locations.getLongitude(i), locations.getLatitude(i)); + + Feature pointFeature = Feature.fromGeometry(point, new JsonObject(), String.valueOf(locations.getLocationId(i))); + pointFeature.addBooleanProperty(MARKER_SELECTED, false); + pointFeature.addBooleanProperty(LAST_LOCATION, false); + pointFeature.addNumberProperty(CONTACT_ID, contactId); + pointFeature.addNumberProperty(TIMESTAMP, locations.getTimestamp(i)); + pointFeature.addNumberProperty(MESSAGE_ID, locations.getMsgId(i)); + pointFeature.addNumberProperty(ACCURACY, locations.getAccuracy(i)); + sortedPointFeatures.add(pointFeature); + + if (i > 0) { + Point lastPoint = (Point) sortedPointFeatures.get(i - 1).geometry(); + ArrayList lineSegmentPoints = new ArrayList<>(3); + lineSegmentPoints.add(lastPoint); + lineSegmentPoints.add(point); + LineString l = LineString.fromLngLats(lineSegmentPoints); + Feature lineFeature = Feature.fromGeometry(l, new JsonObject(), "l_" + pointFeature.id()); + lineFeature.addNumberProperty(TIMESTAMP, pointFeature.getNumberProperty(TIMESTAMP)); + sortedLineFeatures.add(lineFeature); + } + + if (boundingBuilder != null) { + boundingBuilder.include(new LatLng(locations.getLatitude(i), locations.getLongitude(i))); + } + } + + if (sortedPointFeatures.size() > 0) { + sortedPointFeatures.get(0).addBooleanProperty(LAST_LOCATION, true); + } + + featureCollections.put(contactMapMetadata.getMarkerFeatureCollection(), sortedPointFeatures); + featureCollections.put(contactMapMetadata.getLineFeatureCollection(), sortedLineFeatures); + + + + //Log.d(TAG, "update Source took " + (System.currentTimeMillis() - start) + " ms"); + } + + +} diff --git a/src/org/thoughtcrime/securesms/map/MapActivity.java b/src/org/thoughtcrime/securesms/map/MapActivity.java index e994238a3..6b3ad3dc5 100644 --- a/src/org/thoughtcrime/securesms/map/MapActivity.java +++ b/src/org/thoughtcrime/securesms/map/MapActivity.java @@ -235,11 +235,4 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid } - @Override - public void onFilterLastPosition(long startTimestamp) { - if (this.mapboxMap == null) { - return; - } - mapDataManager.filterLastPositions(startTimestamp); - } } diff --git a/src/org/thoughtcrime/securesms/map/MapDataManager.java b/src/org/thoughtcrime/securesms/map/MapDataManager.java index ec5ef8638..94e472957 100644 --- a/src/org/thoughtcrime/securesms/map/MapDataManager.java +++ b/src/org/thoughtcrime/securesms/map/MapDataManager.java @@ -21,6 +21,7 @@ import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.LineString; import com.mapbox.geojson.Point; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -35,21 +36,24 @@ import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.connect.ApplicationDcContext; import org.thoughtcrime.securesms.connect.DcHelper; -import org.thoughtcrime.securesms.map.model.FeatureTreeSet; import org.thoughtcrime.securesms.map.model.FilterProvider; import org.thoughtcrime.securesms.map.model.MapSource; -import org.thoughtcrime.securesms.map.model.TimeComparableFeature; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedList; import java.util.Map; import static com.b44t.messenger.DcContext.DC_EVENT_LOCATION_CHANGED; import static com.b44t.messenger.DcContext.DC_GCL_ADD_SELF; +import static com.mapbox.mapboxsdk.style.expressions.Expression.all; import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; +import static com.mapbox.mapboxsdk.style.expressions.Expression.neq; import static com.mapbox.mapboxsdk.style.expressions.Expression.get; +import static com.mapbox.mapboxsdk.style.expressions.Expression.length; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.not; import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; import static com.mapbox.mapboxsdk.style.expressions.Expression.toBool; import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_BOTTOM_LEFT; @@ -57,11 +61,20 @@ import static com.mapbox.mapboxsdk.style.layers.Property.NONE; import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAnchor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOpacity; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; import static org.thoughtcrime.securesms.map.model.MapSource.INFO_WINDOW_LAYER; +import static org.thoughtcrime.securesms.map.model.MapSource.LINE_FEATURE_LIST; /** @@ -76,7 +89,13 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn public static final String TIMESTAMP = "TIMESTAMP"; public static final String MESSAGE_ID = "MESSAGE_ID"; public static final String ACCURACY = "ACCURACY"; + public static final String MARKER_CHAR = "MARKER_CHAR"; + public static final String MARKER_ICON = "MARKER_ICON"; + public static final String LAST_POSITION_ICON = "LAST_POSITION_ICON"; private static final String INFO_WINDOW_SRC = "INFO_WINDOW_SRC"; + private static final String LAST_POSITION_LAYER = "LAST_POSITION_LAYER"; + private static final String LAST_POSITION_SOURCE = "LAST_POSITION_SRC"; + private static final String LAST_POSITION_ICON_ID = "LAST_POSITION_ICN_ID"; public static final int ALL_CHATS_GLOBAL_MAP = 0; public static final long TIMESTAMP_NOW = 0L; @@ -86,7 +105,8 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private static final String TAG = MapDataManager.class.getSimpleName(); private Style mapboxStyle; private HashMap contactMapSources = new HashMap<>(); - private HashMap featureCollections = new HashMap<>(); + private HashMap> featureCollections = new HashMap<>(); + private HashMap lastPositions = new HashMap<>(); private FilterProvider filterProvider = new FilterProvider(); private Feature selectedFeature; private int chatId; @@ -108,14 +128,19 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn int[] contactIds = getContactIds(chatId); initInfoWindowLayer(); + initLastPositionLayer(); filterProvider.setMessageFilter(true); - filterProvider.setLastPositionFilter(System.currentTimeMillis() - DEFAULT_LAST_POSITION_DELTA); + long now = System.currentTimeMillis(); + filterProvider.setRangeFilter(now - DEFAULT_LAST_POSITION_DELTA, now); + applyLastPositionFilter(); for (int contactId : contactIds) { updateSource(chatId, contactId, boundingBuilder); MapSource source = contactMapSources.get(contactId); - applyMarkerFilter(source); - applyLineFilter(source); + if (source != null) { + applyMarkerFilter(source); + applyLineFilter(source); + } } dcContext.eventCenter.addObserver(DC_EVENT_LOCATION_CHANGED, this); @@ -150,9 +175,14 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn public void refreshSource(int contactId) { MapSource source = contactMapSources.get(contactId); - FeatureTreeSet collection = featureCollections.get(source.getMarkerFeatureCollection()); + LinkedList collection = featureCollections.get(source.getMarkerFeatureCollection()); GeoJsonSource pointSource = (GeoJsonSource) mapboxStyle.getSource(source.getMarkerSource()); - pointSource.setGeoJson(FeatureCollection.fromFeatures(collection.getFeatureList())); + pointSource.setGeoJson(FeatureCollection.fromFeatures(collection)); + LinkedList lineFeatures = featureCollections.get(source.getLineFeatureCollection()); + GeoJsonSource lineSource = (GeoJsonSource) mapboxStyle.getSource(source.getLineSource()); + lineSource.setGeoJson(FeatureCollection.fromFeatures(lineFeatures)); + GeoJsonSource lastPostionSource = (GeoJsonSource) mapboxStyle.getSource(LAST_POSITION_SOURCE); + lastPostionSource.setGeoJson(FeatureCollection.fromFeatures(new LinkedList<>(lastPositions.values()))); } @Override @@ -162,6 +192,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn if (contactMapSources.containsKey(contactId)) { updateSource(chatId, contactId); } + Log.d(TAG, "updateEvent in MapDataManager called. finished: " + eventId); } @Override @@ -171,13 +202,14 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn public String[] getMarkerLayers() { - String markerLayers[] = new String[contactMapSources.size()]; + String markerLayers[] = new String[contactMapSources.size() + 1]; int i = 0; for (Map.Entry entry : contactMapSources.entrySet()) { markerLayers[i] = entry.getValue().getMarkerLayer(); i += 1; } + markerLayers[contactMapSources.size()] = LAST_POSITION_LAYER; return markerLayers; } @@ -219,12 +251,6 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn applyFilters(contactIds); } - public void filterLastPositions(long startTimestamp) { - int[] contactIds = getContactIds(chatId); - filterProvider.setLastPositionFilter(startTimestamp); - applyFilters(contactIds); - } - public void showTraces(boolean show) { int[] contactIds = getContactIds(chatId); this.showTraces = show; @@ -240,10 +266,19 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private void applyFilters(int[] contactIds) { for (int contactId : contactIds) { MapSource contactMapMetadata = contactMapSources.get(contactId); + if (contactMapMetadata == null) { + continue; + } showLineLayer(contactMapMetadata); applyMarkerFilter(contactMapMetadata); applyLineFilter(contactMapMetadata); } + applyLastPositionFilter(); + } + + private void applyLastPositionFilter() { + SymbolLayer markerLayer = (SymbolLayer) mapboxStyle.getLayer(LAST_POSITION_LAYER); + markerLayer.setFilter(filterProvider.getRangeFilter()); } private void applyMarkerFilter(MapSource source) { @@ -253,7 +288,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private void applyLineFilter(MapSource source) { LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(source.getLineLayer()); - lineLayer.setFilter(filterProvider.getLineFilter()); + lineLayer.setFilter(filterProvider.getRangeFilter()); } private void updateSource(int chatId, int contactId) { @@ -267,27 +302,54 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private void updateSource(int chatId, int contactId, long startTimestamp, long endTimestamp, LatLngBounds.Builder boundingBuilder) { //long start = System.currentTimeMillis(); DcArray locations = dcContext.getLocations(chatId, contactId, startTimestamp, endTimestamp); + int count = locations.getCnt(); + if (count == 0) { + return; + } + MapSource contactMapMetadata = contactMapSources.get(contactId); if (contactMapMetadata == null) { contactMapMetadata = addContactMapSource(contactId); } - FeatureTreeSet sortedPointFeatures = featureCollections.get(contactMapMetadata.getMarkerFeatureCollection()); - if (sortedPointFeatures == null) { - sortedPointFeatures = new FeatureTreeSet(); + LinkedList sortedPointFeatures = featureCollections.get(contactMapMetadata.getMarkerFeatureCollection()); + if (sortedPointFeatures != null && sortedPointFeatures.size() == count) { + return; + } else { + sortedPointFeatures = new LinkedList<>(); } + LinkedList sortedLineFeatures = new LinkedList<>(); - int count = locations.getCnt(); - for (int i = 0; i < count; i++) { - Point p = Point.fromLngLat(locations.getLongitude(i), locations.getLatitude(i)); - Feature pointFeature = Feature.fromGeometry(p, new JsonObject(), String.valueOf(locations.getLocationId(i))); + for (int i = count - 1; i >= 0; i--) { + Point point = Point.fromLngLat(locations.getLongitude(i), locations.getLatitude(i)); + + String codepointChar = + locations.getMarker(i) != null ? + locations.getMarker(i) : + ""; + Log.d(TAG, "codepointChar: " + codepointChar); + + Feature pointFeature = Feature.fromGeometry(point, new JsonObject(), String.valueOf(locations.getLocationId(i))); pointFeature.addBooleanProperty(MARKER_SELECTED, false); pointFeature.addBooleanProperty(LAST_LOCATION, false); pointFeature.addNumberProperty(CONTACT_ID, contactId); pointFeature.addNumberProperty(TIMESTAMP, locations.getTimestamp(i)); pointFeature.addNumberProperty(MESSAGE_ID, locations.getMsgId(i)); pointFeature.addNumberProperty(ACCURACY, locations.getAccuracy(i)); - sortedPointFeatures.add(new TimeComparableFeature(pointFeature)); + pointFeature.addStringProperty(MARKER_CHAR, codepointChar); + pointFeature.addStringProperty(MARKER_ICON, contactMapMetadata.getMarkerIcon()); + sortedPointFeatures.addFirst(pointFeature); + + if (sortedPointFeatures.size() > 1) { + Point lastPoint = (Point) sortedPointFeatures.get(1).geometry(); + ArrayList lineSegmentPoints = new ArrayList<>(3); + lineSegmentPoints.add(lastPoint); + lineSegmentPoints.add(point); + LineString l = LineString.fromLngLats(lineSegmentPoints); + Feature lineFeature = Feature.fromGeometry(l, new JsonObject(), "l_" + pointFeature.id()); + lineFeature.addNumberProperty(TIMESTAMP, pointFeature.getNumberProperty(TIMESTAMP)); + sortedLineFeatures.addFirst(lineFeature); + } if (boundingBuilder != null) { boundingBuilder.include(new LatLng(locations.getLatitude(i), locations.getLongitude(i))); @@ -295,30 +357,17 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn } if (sortedPointFeatures.size() > 0) { - sortedPointFeatures.first().getFeature().addBooleanProperty(LAST_LOCATION, true); + Feature lastPostion = sortedPointFeatures.getFirst(); + lastPostion.addStringProperty(LAST_POSITION_ICON, contactMapMetadata.getMarkerLastPositon()); + lastPostion.removeProperty(MARKER_ICON); + lastPostion.addBooleanProperty(LAST_LOCATION, true); + lastPositions.put(contactId, lastPostion); } - ArrayList sortedPointList = sortedPointFeatures.getPointList(); - ArrayList sortedFeatureList = sortedPointFeatures.getFeatureList(); - FeatureCollection pointFeatureCollection = FeatureCollection.fromFeatures(sortedFeatureList); - ArrayList lineFeatures = new ArrayList<>(); - - for (int i = 0; i < sortedPointFeatures.size() - 1; i++) { - Feature f = sortedFeatureList.get(i); - Number numberProperty = f.getNumberProperty(TIMESTAMP); - LineString l = LineString.fromLngLats(sortedPointList.subList(i, i+2)); - Feature lineFeature = Feature.fromGeometry(l, new JsonObject(), "l_" + f.id()); - lineFeature.addNumberProperty(TIMESTAMP, numberProperty); - lineFeatures.add(lineFeature); - } - - FeatureCollection lineFeatureCollection = FeatureCollection.fromFeatures(lineFeatures); - - GeoJsonSource lineSource = (GeoJsonSource) mapboxStyle.getSource(contactMapMetadata.getLineSource()); - lineSource.setGeoJson(lineFeatureCollection); - GeoJsonSource pointSource = (GeoJsonSource) mapboxStyle.getSource(contactMapMetadata.getMarkerSource()); - pointSource.setGeoJson(pointFeatureCollection); featureCollections.put(contactMapMetadata.getMarkerFeatureCollection(), sortedPointFeatures); + featureCollections.put(contactMapMetadata.getLineFeatureCollection(), sortedLineFeatures); + + refreshSource(contactId); //Log.d(TAG, "update Source took " + (System.currentTimeMillis() - start) + " ms"); } @@ -371,6 +420,20 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn )); } + private void initLastPositionLayer() { + GeoJsonSource lastPositionSource = new GeoJsonSource(LAST_POSITION_SOURCE); + mapboxStyle.addSource(lastPositionSource); + Expression markerSize = + switchCase(toBool(get(MARKER_SELECTED)), literal(1.75f), literal(1.25f)); + mapboxStyle.addLayerBelow(new SymbolLayer(LAST_POSITION_LAYER, LAST_POSITION_SOURCE).withProperties( + iconImage(get(LAST_POSITION_ICON)), + /* all info window and marker image to appear at the same time*/ + iconAllowOverlap(true), + iconIgnorePlacement(true), + iconSize(markerSize) + ).withFilter(filterProvider.getRangeFilter()), INFO_WINDOW_LAYER); + } + private void initContactBasedLayers(MapSource source) { mapboxStyle.addImage(source.getMarkerLastPositon(), generateColoredLastPositionIcon(source.getColorArgb())); @@ -378,26 +441,39 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn generateColoredLocationIcon(source.getColorArgb())); Expression markerSize = - switchCase(toBool(get(MARKER_SELECTED)), literal(1.5f), - switchCase(toBool(get(LAST_LOCATION)), literal(1.0f), - switchCase(eq(get(MESSAGE_ID), literal(0)), literal(0.7f), literal(1.1f)))); - Expression markerIcon = switchCase(toBool(get(LAST_LOCATION)), literal(source.getMarkerLastPositon()), literal(source.getMarkerIcon())); - - mapboxStyle.addLayerBelow(new SymbolLayer(source.getMarkerLayer(), source.getMarkerSource()) - .withProperties( - iconImage(markerIcon), - iconSize(markerSize)) - .withFilter(filterProvider.getMarkerFilter()), - INFO_WINDOW_LAYER); + switchCase( + neq(length(get(MARKER_CHAR)), literal(0)), + switchCase(toBool(get(MARKER_SELECTED)), literal(2.25f), literal(2.0f)), + eq(get(MESSAGE_ID), literal(0)), + switchCase(toBool(get(MARKER_SELECTED)), literal(1.1f), literal(1.0f)), + switchCase(toBool(get(MARKER_SELECTED)), literal(1.1f), literal(0.7f))); + Expression markerIcon = get(MARKER_ICON); mapboxStyle.addLayerBelow(new LineLayer(source.getLineLayer(), source.getLineSource()) .withProperties(PropertyFactory.lineCap(Property.LINE_CAP_ROUND), - PropertyFactory.lineJoin(Property.LINE_JOIN_ROUND), - PropertyFactory.lineWidth(3f), - PropertyFactory.lineOpacity(0.5f), - PropertyFactory.lineColor(source.getColorArgb()), - PropertyFactory.visibility(NONE)), - INFO_WINDOW_LAYER); + lineJoin(Property.LINE_JOIN_ROUND), + lineWidth(3f), + lineOpacity(0.5f), + lineColor(source.getColorArgb()), + visibility(NONE) + ) + .withFilter(filterProvider.getRangeFilter()), + LAST_POSITION_LAYER); + + + mapboxStyle.addLayerBelow(new SymbolLayer(source.getMarkerLayer(), source.getMarkerSource()) + .withProperties( + iconImage(markerIcon), + iconSize(markerSize), + textAllowOverlap(true), + textIgnorePlacement(true), + iconIgnorePlacement(false), + iconAllowOverlap(false), + textField(get(MARKER_CHAR)) + ) + .withFilter(all(filterProvider.getMarkerFilter(), + not(get(LAST_LOCATION)))), + LAST_POSITION_LAYER); } private MapSource addContactMapSource(int contactId) { @@ -415,7 +491,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn } private Bitmap generateColoredLastPositionIcon(int colorFilter) { - return generateColoredBitmap(colorFilter, R.drawable.ic_location_on_white_24dp); + return generateColoredBitmap(colorFilter, R.drawable.ic_location_on_white_48dp); } private Bitmap generateColoredLocationIcon(int colorFilter) { @@ -480,7 +556,10 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private Feature getFeatureWithId(String id) { for (String key : featureCollections.keySet()) { - ArrayList featureCollection = featureCollections.get(key).getFeatureList(); + if (key.startsWith(LINE_FEATURE_LIST)) { + continue; + } + LinkedList featureCollection = featureCollections.get(key); for (Feature f : featureCollection) { if (f.id().equals(id)) { return f; diff --git a/src/org/thoughtcrime/securesms/map/model/FeatureTreeSet.java b/src/org/thoughtcrime/securesms/map/model/FeatureTreeSet.java deleted file mode 100644 index 0a5a80c00..000000000 --- a/src/org/thoughtcrime/securesms/map/model/FeatureTreeSet.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.thoughtcrime.securesms.map.model; - -import android.support.annotation.NonNull; - -import com.google.gson.JsonSyntaxException; -import com.mapbox.geojson.Feature; -import com.mapbox.geojson.Point; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.TreeSet; - -/** - * Created by cyberta on 21.03.19. - */ - -public class FeatureTreeSet extends TreeSet { - - /** - * - * @param obj - * @return true if element was added newly, false if element was replaced - */ - @Override - public boolean add(@NonNull TimeComparableFeature obj) { - boolean existed = remove(obj); - super.add(obj); - return !existed; - } - - public ArrayList getFeatureList() { - ArrayList featureList = new ArrayList<>(); - Iterator iterator = this.iterator(); - while (iterator.hasNext()) { - TimeComparableFeature timeComparableFeature = iterator.next(); - featureList.add(timeComparableFeature.getFeature()); - } - return featureList; - } - - public ArrayList getPointList() { - ArrayList points = new ArrayList<>(); - Iterator iterator = this.iterator(); - while (iterator.hasNext()) { - TimeComparableFeature timeComparableFeature = iterator.next(); - try { - points.add(Point.fromJson(timeComparableFeature.getFeature().geometry().toJson())); - } catch (JsonSyntaxException | NullPointerException e) { - e.printStackTrace(); - } - } - return points; - } -} diff --git a/src/org/thoughtcrime/securesms/map/model/FilterProvider.java b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java index ffb42701a..667d66fa0 100644 --- a/src/org/thoughtcrime/securesms/map/model/FilterProvider.java +++ b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java @@ -7,16 +7,13 @@ import com.mapbox.mapboxsdk.style.expressions.Expression; import java.util.HashMap; import static com.mapbox.mapboxsdk.style.expressions.Expression.all; -import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; import static com.mapbox.mapboxsdk.style.expressions.Expression.get; import static com.mapbox.mapboxsdk.style.expressions.Expression.gte; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; import static com.mapbox.mapboxsdk.style.expressions.Expression.lte; import static com.mapbox.mapboxsdk.style.expressions.Expression.neq; -import static org.thoughtcrime.securesms.map.MapDataManager.LAST_LOCATION; import static org.thoughtcrime.securesms.map.MapDataManager.MESSAGE_ID; import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; -import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.LAST_POSITION; import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.MESSAGES; import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.RANGE; @@ -27,7 +24,6 @@ import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.RAN public class FilterProvider { public enum FilterType { RANGE, - LAST_POSITION, MESSAGES } @@ -35,17 +31,9 @@ public class FilterProvider { public void setRangeFilter(long startTimestamp, long endTimestamp) { - expressions.remove(LAST_POSITION); addFilter(RANGE, all( lte(get(TIMESTAMP), endTimestamp), gte(get(TIMESTAMP), startTimestamp))); - - } - public void setLastPositionFilter(long startTimestamp) { - expressions.remove(RANGE); - addFilter(LAST_POSITION, all( - eq((get(LAST_LOCATION)), literal(true)), - gte(get(TIMESTAMP), startTimestamp))); } public void setMessageFilter(boolean filter) { @@ -68,13 +56,10 @@ public class FilterProvider { return all(expressions.values().toArray(new Expression[expressions.values().size()])); } - public Expression getLineFilter() { - if (expressions.get(LAST_POSITION) != null) { - return expressions.get(LAST_POSITION); - } else if (expressions.get(RANGE) != null) { + public Expression getRangeFilter() { + if (expressions.get(RANGE) != null) { return expressions.get(RANGE); } - return all(); } diff --git a/src/org/thoughtcrime/securesms/map/model/MapSource.java b/src/org/thoughtcrime/securesms/map/model/MapSource.java index f0b4febd5..1926104c3 100644 --- a/src/org/thoughtcrime/securesms/map/model/MapSource.java +++ b/src/org/thoughtcrime/securesms/map/model/MapSource.java @@ -15,6 +15,7 @@ public class MapSource { public static final String MARKER_ICON = "marker_icon_id"; public static final String MARKER_LAST_POSITON = "marker_last_position"; public static final String MARKER_FEATURE_LIST = "marker_feature_list"; + public static final String LINE_FEATURE_LIST = "line_feature_list"; private final String markerSource; private final String lineSource; @@ -25,19 +26,20 @@ public class MapSource { private final String markerIcon; private final String markerLastPositon; private final String markerFeatureCollection; + private final String lineFeatureCollection; private int color; private int colorArgb; - public MapSource(int chatId) { - markerSource = MARKER_POSITION_SOURCE + "_" + chatId; - lineSource = LINE_SOURCE + "_" + chatId; - markerLayer = MARKER_LAYER + "_" + chatId; - lineLayer = LINE_LAYER + "_" + chatId; - markerIcon = MARKER_ICON + "_" + chatId; - markerLastPositon = MARKER_LAST_POSITON + "_" + chatId; - markerFeatureCollection = MARKER_FEATURE_LIST + "_" + chatId; - + public MapSource(int contactId) { + markerSource = MARKER_POSITION_SOURCE + "_" + contactId; + lineSource = LINE_SOURCE + "_" + contactId; + markerLayer = MARKER_LAYER + "_" + contactId; + lineLayer = LINE_LAYER + "_" + contactId; + markerIcon = MARKER_ICON + "_" + contactId; + markerLastPositon = MARKER_LAST_POSITON + "_" + contactId; + markerFeatureCollection = MARKER_FEATURE_LIST + "_" + contactId; + lineFeatureCollection = LINE_FEATURE_LIST + "_" + contactId; } public void setColor(int color) { @@ -79,4 +81,6 @@ public class MapSource { public String getMarkerFeatureCollection() { return markerFeatureCollection; } + public String getLineFeatureCollection() { return lineFeatureCollection; } + } diff --git a/src/org/thoughtcrime/securesms/map/model/TimeComparableFeature.java b/src/org/thoughtcrime/securesms/map/model/TimeComparableFeature.java deleted file mode 100644 index 7b80185d1..000000000 --- a/src/org/thoughtcrime/securesms/map/model/TimeComparableFeature.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.thoughtcrime.securesms.map.model; - -import android.support.annotation.NonNull; - -import com.mapbox.geojson.Feature; - -import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; - -/** - * Created by cyberta on 21.03.19. - */ - -public class TimeComparableFeature implements Comparable { - private Feature feature; - - public TimeComparableFeature(@NonNull Feature feature) { - if (!feature.hasProperty(TIMESTAMP)) { - throw new IllegalArgumentException("Time comparable features need to have a TIMESTAMP property"); - } - - this.feature = feature; - } - - public Feature getFeature() { - return feature; - } - - /** - * - * @param o for same timestamps but different featureIds, this object is considered lower - * @return - */ - @Override - public int compareTo(@NonNull TimeComparableFeature o) { - if (this.equals(o) && this.feature.getNumberProperty(TIMESTAMP).longValue() == o.getFeature().getNumberProperty(TIMESTAMP).longValue()) { - return 0; - } - return this.feature.getNumberProperty(TIMESTAMP).longValue() > o.getFeature().getNumberProperty(TIMESTAMP).longValue() ? -1 : 1; - } - - - @Override - public int hashCode() { - return this.feature.id().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof TimeComparableFeature)) { - return false; - } - - TimeComparableFeature compare = (TimeComparableFeature) obj; - return this.feature.id() != null && - compare.feature.id() != null && - this.feature.id().equals(compare.feature.id()); - } - -} diff --git a/test/org/thoughtcrime/securesms/map/model/FeatureTreeSetTest.java b/test/org/thoughtcrime/securesms/map/model/FeatureTreeSetTest.java deleted file mode 100644 index 6b7a52b52..000000000 --- a/test/org/thoughtcrime/securesms/map/model/FeatureTreeSetTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.thoughtcrime.securesms.map.model; - -import com.mapbox.geojson.Feature; -import com.mapbox.geojson.Point; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Iterator; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; -import static utils.TestUtils.getPointFeature; - -/** - * Created by cyberta on 22.03.19. - */ -public class FeatureTreeSetTest { - - @Test - public void add_differentFeaturesIds_differentTimestamps_descendingOrder() { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - - Feature point2 = getPointFeature("3"); - point2.addNumberProperty(TIMESTAMP, 2); - featureTreeSet.add(new TimeComparableFeature(point2)); - - Feature point = getPointFeature("2"); - point.addNumberProperty(TIMESTAMP, 1); - featureTreeSet.add(new TimeComparableFeature(point)); - - featureTreeSet.add(new TimeComparableFeature(getPointFeature("1"))); - - Iterator iterator = featureTreeSet.iterator(); - assertEquals(123456789, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - assertEquals(2, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - assertEquals(1, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - - } - - - @Test - public void add_sameFeaturesIds_differentTimestamps_descendingOrder() { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - - Feature point2 = getPointFeature(); - point2.addNumberProperty(TIMESTAMP, 2); - featureTreeSet.add(new TimeComparableFeature(point2)); - - Feature point = getPointFeature(); - point.addNumberProperty(TIMESTAMP, 1); - featureTreeSet.add(new TimeComparableFeature(point)); - - featureTreeSet.add(new TimeComparableFeature(getPointFeature("1"))); - - - Iterator iterator = featureTreeSet.iterator(); - assertEquals(123456789, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - assertEquals(2, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - assertEquals(1, iterator.next().getFeature().getNumberProperty(TIMESTAMP).longValue()); - } - - @Test - public void add_sameFeaturesIds_sameTimestamps_noDuplicatedEntries() { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - featureTreeSet.add(new TimeComparableFeature(getPointFeature())); - featureTreeSet.add(new TimeComparableFeature(getPointFeature())); - assertEquals(1, featureTreeSet.size()); - } - - @Test - public void add_sameFeaturesIds_sameTimestamps_elementReplaced() { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - Feature feature = getPointFeature(); - feature.addStringProperty("Test", "element1"); - featureTreeSet.add(new TimeComparableFeature(feature)); - featureTreeSet.add(new TimeComparableFeature(getPointFeature())); - assertFalse(featureTreeSet.first().getFeature().hasProperty("Test")); - } - - - - @Test - public void getFeatureList_returnsOrderedList() throws Exception { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - - Feature point2 = getPointFeature(); - point2.addNumberProperty(TIMESTAMP, 2); - featureTreeSet.add(new TimeComparableFeature(point2)); - - Feature point = getPointFeature(); - point.addNumberProperty(TIMESTAMP, 1); - featureTreeSet.add(new TimeComparableFeature(point)); - - featureTreeSet.add(new TimeComparableFeature(getPointFeature("1"))); - - ArrayList features = featureTreeSet.getFeatureList(); - assertEquals(123456789, features.get(0).getNumberProperty(TIMESTAMP).longValue()); - assertEquals(2, features.get(1).getNumberProperty(TIMESTAMP).longValue()); - assertEquals(1, features.get(2).getNumberProperty(TIMESTAMP).longValue()); - - } - - @Test - public void getPointList_returnsOrderedPointList() throws Exception { - FeatureTreeSet featureTreeSet = new FeatureTreeSet(); - - Feature point = getPointFeature("id2", 1.00, 1.00); - point.addNumberProperty(TIMESTAMP, 2); - featureTreeSet.add(new TimeComparableFeature(point)); - - Feature point2 = getPointFeature("id1", 2.00, 2.00); - point2.addNumberProperty(TIMESTAMP, 1); - featureTreeSet.add(new TimeComparableFeature(point2)); - - - Feature point3 = getPointFeature("id3", 3.00, 3.00); - point3.addNumberProperty(TIMESTAMP, 3); - - featureTreeSet.add(new TimeComparableFeature(point3)); - - - ArrayList points = featureTreeSet.getPointList(); - assertEquals(new Double(3.00), points.get(0).coordinates().get(0)); - assertEquals(new Double(1.00), points.get(1).coordinates().get(0)); - assertEquals(new Double(2.00), points.get(2).coordinates().get(0)); - - } - -} \ No newline at end of file diff --git a/test/org/thoughtcrime/securesms/map/model/TimeComparableFeatureTest.java b/test/org/thoughtcrime/securesms/map/model/TimeComparableFeatureTest.java deleted file mode 100644 index 9dd4f48aa..000000000 --- a/test/org/thoughtcrime/securesms/map/model/TimeComparableFeatureTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.thoughtcrime.securesms.map.model; - -import com.mapbox.geojson.Feature; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; -import static utils.TestUtils.getPointFeature; - -/** - * Created by cyberta on 22.03.19. - */ - -public class TimeComparableFeatureTest { - - @Test(expected = IllegalArgumentException.class) - public void init_noTimestamp_throwIllegalStateException() throws Exception { - Feature feature = getPointFeature(); - feature.removeProperty(TIMESTAMP); - new TimeComparableFeature(feature); - } - - @Test - public void compareTo_sameTimestamp_return0() throws Exception { - TimeComparableFeature tcf1 = new TimeComparableFeature(getPointFeature()); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(0, tcf1.compareTo(tcf2)); - assertEquals(0, tcf2.compareTo(tcf1)); - } - - @Test - public void compareTo_biggerTimestamp_return1() throws Exception { - Feature feature = getPointFeature(); - feature.addNumberProperty(TIMESTAMP, 234567890); - TimeComparableFeature tcf1 = new TimeComparableFeature(getPointFeature()); - TimeComparableFeature tcf2 = new TimeComparableFeature(feature); - - assertEquals(1, tcf1.compareTo(tcf2)); - } - - @Test - public void compareTo_biggerTimestamp_returnMinus1() throws Exception { - Feature feature = getPointFeature(); - feature.addNumberProperty(TIMESTAMP, 234567890); - TimeComparableFeature tcf1 = new TimeComparableFeature(feature); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(-1, tcf1.compareTo(tcf2)); - } - - @Test - public void compareTo_sameTimestamp_differntId_returnMinus1() throws Exception { - Feature feature = getPointFeature(); - feature.addNumberProperty(TIMESTAMP, 234567890); - TimeComparableFeature tcf1 = new TimeComparableFeature(feature); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(-1, tcf1.compareTo(tcf2)); - } - - @Test - public void equals_differentObjects_sameId_returnTrue() throws Exception { - TimeComparableFeature tcf1 = new TimeComparableFeature(getPointFeature()); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(true, tcf1.equals(tcf2)); - } - - @Test - public void equals_differentObjects_differentId_returnFalse() throws Exception { - Feature feature = getPointFeature("id2"); - TimeComparableFeature tcf1 = new TimeComparableFeature(feature); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(false, tcf1.equals(tcf2)); - } - - @Test - public void equals_differentObjects_differentId_sameTimeStamp_returnFalse() throws Exception { - Feature feature = getPointFeature("id2"); - TimeComparableFeature tcf1 = new TimeComparableFeature(feature); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(false, tcf1.equals(tcf2)); - } - - @Test - public void equals_differentObjects_sameId_differentTimeStamp_returnTrue() throws Exception { - Feature feature = getPointFeature(); - feature.addNumberProperty(TIMESTAMP, 234567890); - TimeComparableFeature tcf1 = new TimeComparableFeature(feature); - TimeComparableFeature tcf2 = new TimeComparableFeature(getPointFeature()); - - assertEquals(true, tcf1.equals(tcf2)); - } - -} \ No newline at end of file diff --git a/test/utils/TestUtils.java b/test/utils/TestUtils.java deleted file mode 100644 index 8a7b7ccfc..000000000 --- a/test/utils/TestUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -package utils; - -import com.google.gson.JsonObject; -import com.mapbox.geojson.Feature; -import com.mapbox.geojson.Point; - -import static org.thoughtcrime.securesms.map.MapDataManager.ACCURACY; -import static org.thoughtcrime.securesms.map.MapDataManager.CONTACT_ID; -import static org.thoughtcrime.securesms.map.MapDataManager.INFO_WINDOW_ID; -import static org.thoughtcrime.securesms.map.MapDataManager.LAST_LOCATION; -import static org.thoughtcrime.securesms.map.MapDataManager.MARKER_SELECTED; -import static org.thoughtcrime.securesms.map.MapDataManager.MESSAGE_ID; -import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; - -/** - * Created by cyberta on 22.03.19. - */ - -public class TestUtils { - - public static Feature getPointFeature(String id) { - return getPointFeature(id, 10.00, 52.00); - } - - public static Feature getPointFeature() { - return getPointFeature("id1"); - } - - public static Feature getPointFeature(String id, double latitude, double longitude) { - Point p = Point.fromLngLat(longitude, latitude); - Feature pointFeature = Feature.fromGeometry(p, new JsonObject(), id); - pointFeature.addBooleanProperty(MARKER_SELECTED, false); - pointFeature.addBooleanProperty(LAST_LOCATION, false); - pointFeature.addNumberProperty(CONTACT_ID, 1); - pointFeature.addStringProperty(INFO_WINDOW_ID, "0_1_info_2"); - pointFeature.addNumberProperty(TIMESTAMP, 123456789); - pointFeature.addNumberProperty(MESSAGE_ID, 1); - pointFeature.addNumberProperty(ACCURACY, 12); - return Feature.fromJson(pointFeature.toJson()); - } - -}