diff --git a/res/layout/bottom_map_sheet.xml b/res/layout/bottom_map_sheet.xml
index dbdd64325..038c28804 100644
--- a/res/layout/bottom_map_sheet.xml
+++ b/res/layout/bottom_map_sheet.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="165dp"
+ android:layout_height="230dp"
android:id="@+id/bottom_sheet"
app:behavior_hideable="false"
app:behavior_peekHeight="35dp"
@@ -36,12 +36,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a46a8b3e4..6f08c72bf 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -220,8 +220,9 @@
No contact requests.\n\nIf you want classic emails to appear here as contact requests, you can change the corresponding setting in the app settings.
- Show location traces in time frame
+ Show locations in time frame
Last position
+ Show traces
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 3e8120a2e..74e2271ea 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -106,4 +106,8 @@
- 12dp
+
+
diff --git a/src/org/thoughtcrime/securesms/map/MapActivity.java b/src/org/thoughtcrime/securesms/map/MapActivity.java
index bed27a00c..37cadb9f3 100644
--- a/src/org/thoughtcrime/securesms/map/MapActivity.java
+++ b/src/org/thoughtcrime/securesms/map/MapActivity.java
@@ -6,6 +6,7 @@ import android.os.Bundle;
import android.support.design.widget.BottomSheetBehavior;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
@@ -49,6 +50,7 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid
private DcLocation dcLocation;
private MapDataManager mapDataManager;
private MapboxMap mapboxMap;
+ SupportMapFragment mapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -64,7 +66,6 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid
dcLocation = DcLocation.getInstance();
- SupportMapFragment mapFragment;
if (savedInstanceState == null) {
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
mapFragment = SupportMapFragment.newInstance();
@@ -165,6 +166,11 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid
return true;
});
}
+
+ SwitchCompat switchCompat = this.findViewById(R.id.locationTraceSwitch);
+ switchCompat.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ mapDataManager.showTraces(isChecked);
+ });
}));
TimeRangeSlider timeRangeSlider = this.findViewById(R.id.timeRangeSlider);
@@ -230,7 +236,7 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid
if (this.mapboxMap == null) {
return;
}
- mapDataManager.filter(startTimestamp, stopTimestamp);
+ mapDataManager.filterRange(startTimestamp, stopTimestamp);
}
diff --git a/src/org/thoughtcrime/securesms/map/MapDataManager.java b/src/org/thoughtcrime/securesms/map/MapDataManager.java
index ad4baabec..ec5ef8638 100644
--- a/src/org/thoughtcrime/securesms/map/MapDataManager.java
+++ b/src/org/thoughtcrime/securesms/map/MapDataManager.java
@@ -36,6 +36,7 @@ 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;
@@ -46,22 +47,23 @@ 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.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.switchCase;
import static com.mapbox.mapboxsdk.style.expressions.Expression.toBool;
import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_BOTTOM_LEFT;
+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.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.visibility;
import static org.thoughtcrime.securesms.map.model.MapSource.INFO_WINDOW_LAYER;
+
/**
* Created by cyberta on 07.03.19.
*/
@@ -83,13 +85,15 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
private static final String TAG = MapDataManager.class.getSimpleName();
private Style mapboxStyle;
- private HashMap contactMapSources;
- private HashMap featureCollections;
+ private HashMap contactMapSources = new HashMap<>();
+ private HashMap featureCollections = new HashMap<>();
+ private FilterProvider filterProvider = new FilterProvider();
private Feature selectedFeature;
private int chatId;
private Context context;
private ApplicationDcContext dcContext;
private boolean isInitial = true;
+ private boolean showTraces = false;
public interface MapDataState {
void onDataInitialized(LatLngBounds bounds);
@@ -100,17 +104,18 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
this.context = context;
this.dcContext = DcHelper.getContext(context);
this.chatId = chatId;
- contactMapSources = new HashMap<>();
- featureCollections = new HashMap<>();
LatLngBounds.Builder boundingBuilder = new LatLngBounds.Builder();
int[] contactIds = getContactIds(chatId);
initInfoWindowLayer();
- long now = System.currentTimeMillis();
+ filterProvider.setMessageFilter(true);
+ filterProvider.setLastPositionFilter(System.currentTimeMillis() - DEFAULT_LAST_POSITION_DELTA);
for (int contactId : contactIds) {
updateSource(chatId, contactId, boundingBuilder);
- filterLastPosition(contactId, now - DEFAULT_LAST_POSITION_DELTA);
+ MapSource source = contactMapSources.get(contactId);
+ applyMarkerFilter(source);
+ applyLineFilter(source);
}
dcContext.eventCenter.addObserver(DC_EVENT_LOCATION_CHANGED, this);
@@ -208,36 +213,47 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
infoWindowSource.setGeoJson(selectedFeature);
}
- public void filter(long startTimestamp, long endTimestamp) {
+ public void filterRange(long startTimestamp, long endTimestamp) {
int[] contactIds = getContactIds(chatId);
- for (int contactId : contactIds) {
- MapSource contactMapMetadata = contactMapSources.get(contactId);
- SymbolLayer markerLayer = (SymbolLayer) mapboxStyle.getLayer(contactMapMetadata.getMarkerLayer());
- Expression filter = all(
- lte(get(TIMESTAMP), endTimestamp),
- gte(get(TIMESTAMP), startTimestamp));
- markerLayer.withFilter(filter);
- LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(contactMapMetadata.getLineLayer());
- lineLayer.withFilter(filter);
- }
+ filterProvider.setRangeFilter(startTimestamp, endTimestamp);
+ 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;
+ filterProvider.setMessageFilter(!show);
+ applyFilters(contactIds);
+ }
+
+ private void showLineLayer(MapSource source) {
+ LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(source.getLineLayer());
+ lineLayer.setProperties(visibility(showTraces ? VISIBLE : NONE));
+ }
+
+ private void applyFilters(int[] contactIds) {
for (int contactId : contactIds) {
- filterLastPosition(contactId, startTimestamp);
+ MapSource contactMapMetadata = contactMapSources.get(contactId);
+ showLineLayer(contactMapMetadata);
+ applyMarkerFilter(contactMapMetadata);
+ applyLineFilter(contactMapMetadata);
}
}
- private void filterLastPosition(int contactId, long startTimestamp) {
- MapSource contactMapMetadata = contactMapSources.get(contactId);
- SymbolLayer markerLayer = (SymbolLayer) mapboxStyle.getLayer(contactMapMetadata.getMarkerLayer());
- Expression filter = all(
- eq((get(LAST_LOCATION)), literal(true)),
- gte(get(TIMESTAMP), startTimestamp));
- markerLayer.withFilter(filter);
- LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(contactMapMetadata.getLineLayer());
- lineLayer.withFilter(filter);
+ private void applyMarkerFilter(MapSource source) {
+ SymbolLayer markerLayer = (SymbolLayer) mapboxStyle.getLayer(source.getMarkerLayer());
+ markerLayer.setFilter(filterProvider.getMarkerFilter());
+ }
+
+ private void applyLineFilter(MapSource source) {
+ LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(source.getLineLayer());
+ lineLayer.setFilter(filterProvider.getLineFilter());
}
private void updateSource(int chatId, int contactId) {
@@ -366,10 +382,12 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
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)),
+ iconSize(markerSize))
+ .withFilter(filterProvider.getMarkerFilter()),
INFO_WINDOW_LAYER);
mapboxStyle.addLayerBelow(new LineLayer(source.getLineLayer(), source.getLineSource())
@@ -377,7 +395,8 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
PropertyFactory.lineJoin(Property.LINE_JOIN_ROUND),
PropertyFactory.lineWidth(3f),
PropertyFactory.lineOpacity(0.5f),
- PropertyFactory.lineColor(source.getColorArgb())),
+ PropertyFactory.lineColor(source.getColorArgb()),
+ PropertyFactory.visibility(NONE)),
INFO_WINDOW_LAYER);
}
@@ -430,15 +449,6 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn
}
}
- private void resetSource(int contactId) {
- MapSource contactMapMetadata = contactMapSources.get(contactId);
- if (contactMapMetadata != null) {
- featureCollections.put(contactMapMetadata.getMarkerFeatureCollection(), new FeatureTreeSet());
- GeoJsonSource pointSource = (GeoJsonSource) mapboxStyle.getSource(contactMapMetadata.getMarkerSource());
- pointSource.setGeoJson(FeatureCollection.fromFeatures(new ArrayList<>()));
- }
- }
-
private void replaceSelectedMarker(String featureId) {
Feature feature = getFeatureWithId(featureId);
feature.addBooleanProperty(MARKER_SELECTED, true);
diff --git a/src/org/thoughtcrime/securesms/map/model/FilterProvider.java b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java
new file mode 100644
index 000000000..ffb42701a
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java
@@ -0,0 +1,81 @@
+package org.thoughtcrime.securesms.map.model;
+
+import android.support.annotation.NonNull;
+
+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;
+
+/**
+ * Created by cyberta on 11.04.19.
+ */
+
+public class FilterProvider {
+ public enum FilterType {
+ RANGE,
+ LAST_POSITION,
+ MESSAGES
+ }
+
+ private HashMap expressions = new HashMap();
+
+
+ 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) {
+ if (filter) {
+ addFilter(MESSAGES, neq(get(MESSAGE_ID), literal(0)));
+ } else {
+ removeFilter(MESSAGES);
+ }
+ }
+
+ private void addFilter(FilterType type, @NonNull Expression expression) {
+ expressions.put(type, expression);
+ }
+
+ public void removeFilter(FilterType type) {
+ expressions.remove(type);
+ }
+
+ public Expression getMarkerFilter() {
+ 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) {
+ return expressions.get(RANGE);
+ }
+
+ return all();
+ }
+
+}