Improve marker browser

This commit is contained in:
Mieszko Wrzeszczyński 2018-11-26 20:22:04 +01:00
parent f0df7b7440
commit 3a2c4f10d4
2 changed files with 110 additions and 42 deletions

View File

@ -4,6 +4,7 @@ import android.Manifest;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.graphics.Color;
import android.location.Location; import android.location.Location;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -22,6 +23,10 @@ import com.getbase.floatingactionbutton.FloatingActionButton;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.mapbox.android.core.permissions.PermissionsListener; import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager; import com.mapbox.android.core.permissions.PermissionsManager;
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.Mapbox;
import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.IconFactory;
@ -35,6 +40,11 @@ import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.Coordinate; import com.uam.wmi.findmytutor.model.Coordinate;
import com.uam.wmi.findmytutor.model.User; import com.uam.wmi.findmytutor.model.User;
@ -47,6 +57,10 @@ import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel; import com.uam.wmi.findmytutor.utils.SharingLevel;
import com.uam.wmi.findmytutor.utils.mapUtils; import com.uam.wmi.findmytutor.utils.mapUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -60,6 +74,22 @@ import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import timber.log.Timber; import timber.log.Timber;
import static com.mapbox.mapboxsdk.style.expressions.Expression.all;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.gt;
import static com.mapbox.mapboxsdk.style.expressions.Expression.gte;
import static com.mapbox.mapboxsdk.style.expressions.Expression.has;
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
import static com.mapbox.mapboxsdk.style.expressions.Expression.lt;
import static com.mapbox.mapboxsdk.style.expressions.Expression.toNumber;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
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.textSize;
public class MapActivity extends BaseActivity public class MapActivity extends BaseActivity
implements PermissionsListener, OnMapReadyCallback { implements PermissionsListener, OnMapReadyCallback {
@ -84,21 +114,21 @@ public class MapActivity extends BaseActivity
private Coordinate droppedMarkercoordinate; private Coordinate droppedMarkercoordinate;
private HashMap<String, Coordinate> coordsMap = new HashMap<>(); private HashMap<String, Coordinate> coordsMap = new HashMap<>();
private HashMap<String, MapMarker> markerHash = new HashMap<>(); private HashMap<String, MapMarker> markerHash = new HashMap<>();
private HashMap<Long, String> markerUserHash = new HashMap<>();
private Set<String> previousCoordsIds = new HashSet<>(); private Set<String> previousCoordsIds = new HashSet<>();
// Camera Animation params // Camera Animation params
private int zoomParam = 17; private int zoomParam = 17;
private int bearingParam = 180; private int bearingParam = 180;
private int tiltParam = 30; private int tiltParam = 30;
private String myID; private String myId;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
myID = PrefUtils.getUserId(getApplicationContext()); myId = PrefUtils.getUserId(getApplicationContext());
// fetching coords service
coordinateService = ApiClient.getClient(getApplicationContext()) coordinateService = ApiClient.getClient(getApplicationContext())
.create(CoordinateService.class); .create(CoordinateService.class);
@ -131,8 +161,9 @@ public class MapActivity extends BaseActivity
enableLocationPlugin(); enableLocationPlugin();
mapboxMap.setOnMarkerClickListener(marker -> { mapboxMap.setOnMarkerClickListener(marker -> {
String id = marker.getTitle(); String id = markerUserHash.get(marker.getId());
if (id.equals(myID)) {
if (id.equals(myId)) {
selectLocationButton.setVisibility(View.GONE); selectLocationButton.setVisibility(View.GONE);
removeLocationButton.setVisibility(View.VISIBLE); removeLocationButton.setVisibility(View.VISIBLE);
@ -174,6 +205,18 @@ public class MapActivity extends BaseActivity
}); });
} }
private void updateUserHashMap(String userId, Long markerId) {
disposable.add(userService.getUserById(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(t -> saveUserToHashMap(t, markerId), this::handleError));
}
private void saveUserToHashMap(User user, Long markerId) {
markerUserHash.put(markerId, user.getId());
markerHash.get(user.getId()).getMarker().setTitle(user.getFirstName() + " " + user.getLastName());
}
private void createMarkerModal(String userId) { private void createMarkerModal(String userId) {
disposable.add(userService.getUserById(userId) disposable.add(userService.getUserById(userId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
@ -195,7 +238,7 @@ public class MapActivity extends BaseActivity
// User cancelled the dialog // User cancelled the dialog
}); });
TextView userName = view.findViewById(R.id. userName); TextView userName = view.findViewById(R.id.userName);
TextView status = view.findViewById(R.id.label); TextView status = view.findViewById(R.id.label);
TextView sharingLevelView = view.findViewById(R.id.sharing_level); TextView sharingLevelView = view.findViewById(R.id.sharing_level);
@ -222,7 +265,6 @@ public class MapActivity extends BaseActivity
message = "Network Error!"; message = "Network Error!";
} }
Toast.makeText(MapActivity.this, message, Toast.LENGTH_SHORT).show(); Toast.makeText(MapActivity.this, message, Toast.LENGTH_SHORT).show();
} }
@ -332,6 +374,7 @@ public class MapActivity extends BaseActivity
@Override @Override
public void onSuccess(List<Coordinate> coordsList) { public void onSuccess(List<Coordinate> coordsList) {
if (coordsList.isEmpty() && tmpLocalMarker != null) { if (coordsList.isEmpty() && tmpLocalMarker != null) {
Timber.e("200 empty []"); Timber.e("200 empty []");
mapboxMap.clear(); mapboxMap.clear();
@ -339,23 +382,22 @@ public class MapActivity extends BaseActivity
} }
ArrayList<String> tmp = new ArrayList<>(); ArrayList<String> tmp = new ArrayList<>();
for (Coordinate coordinate : coordsList) { for (Coordinate coordinate : coordsList) {
tmp.add(coordinate.getUserId()); tmp.add(coordinate.getUserId());
} }
Set<String> currentCoordsIds = new HashSet<>(tmp); Set<String> currentCoordsIds = new HashSet<>(tmp);
if (previousCoordsIds.isEmpty()) { if (previousCoordsIds.isEmpty()) {
previousCoordsIds.addAll(currentCoordsIds); previousCoordsIds.addAll(currentCoordsIds);
} else { } else {
// here we clear + it returns bool if sth was removed // here we clear + it returns bool if sth was removed
if (previousCoordsIds.removeAll(currentCoordsIds)) { if (previousCoordsIds.removeAll(currentCoordsIds)) {
for (String toRemoveId : previousCoordsIds) { for (String toRemoveId : previousCoordsIds) {
Log.e(tag + "delete: ", "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId));
mapboxMap.removeMarker(markerHash.get(toRemoveId).getMarker()); mapboxMap.removeMarker(markerHash.get(toRemoveId).getMarker());
markerHash.remove(toRemoveId); markerHash.remove(toRemoveId);
coordsMap.remove(toRemoveId); coordsMap.remove(toRemoveId);
} }
} else { } else {
// TODO double check when some markers api will change // TODO double check when some markers api will change
@ -370,6 +412,9 @@ public class MapActivity extends BaseActivity
Coordinate coordinate = coordsMap.get(id); Coordinate coordinate = coordsMap.get(id);
Log.e(tag, "hashMapSize: " + coordsMap.size());
Log.e(tag, "markerMapSize: " + coordsMap.size());
if (coordinate != null) { if (coordinate != null) {
boolean isTheSameLocalization = coordinate.getLatitude().equals(element.getLatitude()) || coordinate.getLongitude().equals(element.getLongitude()); boolean isTheSameLocalization = coordinate.getLatitude().equals(element.getLatitude()) || coordinate.getLongitude().equals(element.getLongitude());
@ -377,6 +422,12 @@ public class MapActivity extends BaseActivity
if (!isTheSameLocalization) { if (!isTheSameLocalization) {
//Replace prev marker and animate //Replace prev marker and animate
Marker marker = markerHash.get(id).getMarker(); Marker marker = markerHash.get(id).getMarker();
Boolean showModalAfterAnimation = false;
if(marker.isInfoWindowShown()){
marker.hideInfoWindow();
showModalAfterAnimation = true;
}
LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude()); LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude());
// TODO fix flickiering markers // TODO fix flickiering markers
@ -388,30 +439,26 @@ public class MapActivity extends BaseActivity
markerAnimator.setInterpolator(new LinearInterpolator()); markerAnimator.setInterpolator(new LinearInterpolator());
markerAnimator.start(); markerAnimator.start();
mapboxMap.getMarkerViewManager().update();
coordsMap.put(id, element); coordsMap.put(id, element);
marker.setPosition(toDestination); marker.setPosition(toDestination);
if(showModalAfterAnimation){
mapboxMap.selectMarker(marker);
}
mapboxMap.getMarkerViewManager().update();
} }
} else { } else {
//Add new marker //Add new marker
coordsMap.put(id, element); coordsMap.put(id, element);
String sharingLevel = coordsMap.get(id).getDisplayMode(); String sharingLevel = coordsMap.get(id).getDisplayMode();
Icon defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.exact_localization_marker); Icon defaultIcon = getMapIcon(sharingLevel, id);
if (sharingLevel.equals(SharingLevel.APPROXIMATED.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.approximate_localization_marker);
} else if (sharingLevel.equals(SharingLevel.MANUAL.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.manual_localization_marker);
} else if (id.equals(myID)) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.my_marker);
}
MarkerOptions markerOptions = new MarkerOptions() MarkerOptions markerOptions = new MarkerOptions()
.title(id)
.setIcon(defaultIcon) .setIcon(defaultIcon)
.position(new LatLng(element.getLatitude(), element.getLongitude())); .position(new LatLng(element.getLatitude(), element.getLongitude()));
@ -419,6 +466,8 @@ public class MapActivity extends BaseActivity
MapMarker marker = new MapMarker(markerMapbox, markerOptions, defaultIcon, sharingLevel); MapMarker marker = new MapMarker(markerMapbox, markerOptions, defaultIcon, sharingLevel);
markerHash.put(id, marker); markerHash.put(id, marker);
updateUserHashMap(id, marker.getMarker().getId());
} }
@ -426,18 +475,10 @@ public class MapActivity extends BaseActivity
Boolean newLocalizationMode = markerHash.get(id).getMarkerType().equals(newSharingLevel); Boolean newLocalizationMode = markerHash.get(id).getMarkerType().equals(newSharingLevel);
if (!newLocalizationMode) { if (!newLocalizationMode) {
Icon defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.exact_localization_marker); Icon defaultIcon = getMapIcon(newSharingLevel, id);
MapMarker marker = markerHash.get(id); MapMarker marker = markerHash.get(id);
coordsMap.get(id).setDisplayMode(newSharingLevel); coordsMap.get(id).setDisplayMode(newSharingLevel);
if (newSharingLevel.equals(SharingLevel.APPROXIMATED.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.approximate_localization_marker);
} else if (newSharingLevel.equals(SharingLevel.MANUAL.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.manual_localization_marker);
} else if (id.equals(myID)) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.my_marker);
}
marker.setDefaultIcon(defaultIcon); marker.setDefaultIcon(defaultIcon);
marker.restoreDefaultIcon(); marker.restoreDefaultIcon();
markerHash.get(id).setMarkerType(newSharingLevel); markerHash.get(id).setMarkerType(newSharingLevel);
@ -452,17 +493,27 @@ public class MapActivity extends BaseActivity
previousCoordsIds.addAll(currentCoordsIds); previousCoordsIds.addAll(currentCoordsIds);
} }
@SuppressLint("LongLogTag")
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
if (e instanceof HttpException) { showError(e);
ResponseBody responseBody = ((HttpException) e).response().errorBody();
}
} }
}) })
); );
} }
private Icon getMapIcon(String sharingLevel, String id) {
Icon defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.exact_localization_marker);
if (sharingLevel.equals(SharingLevel.APPROXIMATED.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.approximate_localization_marker);
} else if (sharingLevel.equals(SharingLevel.MANUAL.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.manual_localization_marker);
} else if (id.equals(myId)) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.my_marker);
}
return defaultIcon;
}
@SuppressWarnings({"MissingPermission"}) @SuppressWarnings({"MissingPermission"})
private void enableLocationPlugin() { private void enableLocationPlugin() {
@ -633,23 +684,33 @@ public class MapActivity extends BaseActivity
Icon markedMarker = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.search_marker); Icon markedMarker = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.search_marker);
List<MapMarker> markersToSet = Stream.of(markerHash.values()) Log.e("MARKERS",mapboxMap.getMarkers().toString());
.filter(m -> Stream.of(users).anyMatch(u -> u.getId().equals(m.getMarker().getTitle())))
List<MapMarker> markersToSet = Stream.of(mapboxMap.getMarkers())
.filter(m -> Stream.of(users).anyMatch(u -> u.getId().equals(markerUserHash.get(m.getId()))))
.map(m -> markerUserHash.get(m.getId()))
.map(m -> markerHash.get(m))
.toList(); .toList();
for (MapMarker marker : markersToSet) { for (MapMarker marker : markersToSet) {
marker.getMarker().setIcon(markedMarker); marker.getMarker().setIcon(markedMarker);
if(markersToSet.size() == 1)
mapboxMap.selectMarker(marker.getMarker());
} }
mapboxMap.getMarkerViewManager().update(); mapboxMap.getMarkerViewManager().update();
} }
public void restoreMapMarkers() { public void restoreMapMarkers() {
for (MapMarker marker : markerHash.values()) {
marker.restoreDefaultIcon(); for (Marker marker : mapboxMap.getMarkers()) {
MapMarker markerMap = markerHash.get(markerUserHash.get(marker.getId()));
markerMap.restoreDefaultIcon();
mapboxMap.deselectMarker(marker);
} }
mapboxMap.getMarkerViewManager().update(); mapboxMap.getMarkerViewManager().update();
} }
} }

View File

@ -1,10 +1,16 @@
package com.uam.wmi.findmytutor.utils; package com.uam.wmi.findmytutor.utils;
import android.support.annotation.NonNull;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
public class MapMarker { public class MapMarker{
private MarkerOptions markerOptions; private MarkerOptions markerOptions;
private Marker marker; private Marker marker;
@ -55,4 +61,5 @@ public class MapMarker {
public void setMarkerType(String markerType) { public void setMarkerType(String markerType) {
this.markerType = markerType; this.markerType = markerType;
} }
} }