diff --git a/app/build.gradle b/app/build.gradle index 3c14510..78feb6e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -58,7 +58,7 @@ dependencies { implementation 'com.auth0.android:jwtdecode:1.1.1' implementation 'com.annimon:stream:1.2.1' implementation 'com.google.android.gms:play-services-location:16.0.0' - + implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:4.0.0' // FloatingBarMenu implementation 'com.getbase:floatingactionbutton:1.10.1' diff --git a/app/src/main/assets/building.geojson b/app/src/main/assets/building.geojson new file mode 100644 index 0000000..a151032 --- /dev/null +++ b/app/src/main/assets/building.geojson @@ -0,0 +1,398 @@ +{ + "features": [ + { + "type": "Feature", + "properties": { + "name": "Skrzydło B", + "longitude" : 52.466669, + "latitude" : 16.926624 + }, + "geometry": { + "coordinates": [ + [ + [ + 16.92618, + 52.466248 + ], + [ + 16.926435, + 52.466201 + ], + [ + 16.92646, + 52.466255 + ], + [ + 16.926516, + 52.466244 + ], + [ + 16.926999, + 52.46711 + ], + [ + 16.926796, + 52.467145 + ], + [ + 16.926782, + 52.467117 + ], + [ + 16.926784, + 52.467121 + ], + [ + 16.926691, + 52.467139 + ], + [ + 16.926662, + 52.46709 + ], + [ + 16.926757, + 52.467072 + ], + [ + 16.926544, + 52.466691 + ], + [ + 16.926434, + 52.46671 + ], + [ + 16.926396, + 52.466655 + ], + [ + 16.926519, + 52.466628 + ], + [ + 16.926323, + 52.466281 + ], + [ + 16.926213, + 52.466307 + ], + [ + 16.92618, + 52.466248 + ] + ] + ], + "type": "Polygon" + }, + "id": "41798cf663bc55c10e6c51c3fe174eda" + }, + { + "type": "Feature", + "properties": { + "name": "Biblioteka", + "longitude" : 52.467351, + "latitude" : 16.926900 + }, + "geometry": { + "coordinates": [ + [ + [ + 16.927048, + 52.46721 + ], + [ + 16.926627, + 52.467295 + ], + [ + 16.926732, + 52.467482 + ], + [ + 16.926876, + 52.467461 + ], + [ + 16.926967, + 52.467428 + ], + [ + 16.927014, + 52.467402 + ], + [ + 16.927171, + 52.467359 + ], + [ + 16.9271, + 52.467202 + ], + [ + 16.927048, + 52.46721 + ] + ] + ], + "type": "Polygon" + }, + "id": "7328c3c9dffd3e76be8d3dcef4f58ddc" + }, + { + "type": "Feature", + "properties": { + "name": "Łącznik", + "longitude" : 52.466619, + "latitude" : 16.926860 + }, + "geometry": { + "coordinates": [ + [ + [ + 16.926759, + 52.466683 + ], + [ + 16.927088, + 52.46661 + ], + [ + 16.927019, + 52.466502 + ], + [ + 16.9267, + 52.466571 + ], + [ + 16.926759, + 52.466683 + ] + ] + ], + "type": "Polygon" + }, + "id": "8c19ee28e4c07ece9756fd21f290713b" + }, + { + "type": "Feature", + "properties": { + "name": "Skrzydło A", + "longitude" : 52.466559, + "latitude" : 16.927163 + }, + "geometry": { + "coordinates": [ + [ + [ + 16.926771, + 52.466106 + ], + [ + 16.926898, + 52.466079 + ], + [ + 16.926926, + 52.466126 + ], + [ + 16.927026, + 52.466107 + ], + [ + 16.92723, + 52.466473 + ], + [ + 16.927184, + 52.466483 + ], + [ + 16.927243, + 52.466586 + ], + [ + 16.927334, + 52.46656 + ], + [ + 16.927602, + 52.466889 + ], + [ + 16.927275, + 52.466959 + ], + [ + 16.926771, + 52.466106 + ] + ] + ], + "type": "Polygon" + }, + "id": "c33bfba772c85cc38ae417843d31b1ff" + }, + { + "type": "Feature", + "properties": { + "name": "Aule", + "longitude" : 52.467114, + "latitude" : 16.927621 + + }, + "geometry": { + "coordinates": [ + [ + [ + 16.92731, + 52.467158 + ], + [ + 16.927315, + 52.46718 + ], + [ + 16.927348, + 52.467199 + ], + [ + 16.927393, + 52.467224 + ], + [ + 16.927426, + 52.467239 + ], + [ + 16.927476, + 52.467258 + ], + [ + 16.92755, + 52.467264 + ], + [ + 16.927625, + 52.467263 + ], + [ + 16.927699, + 52.467246 + ], + [ + 16.92776, + 52.467212 + ], + [ + 16.927821, + 52.467158 + ], + [ + 16.927838, + 52.467099 + ], + [ + 16.927827, + 52.467059 + ], + [ + 16.927793, + 52.467012 + ], + [ + 16.927738, + 52.466976 + ], + [ + 16.927661, + 52.466949 + ], + [ + 16.927581, + 52.466939 + ], + [ + 16.927534, + 52.466938 + ], + [ + 16.927467, + 52.466949 + ], + [ + 16.927387, + 52.467047 + ], + [ + 16.927315, + 52.467153 + ], + [ + 16.92731, + 52.467158 + ] + ] + ], + "type": "Polygon" + }, + "id": "c779419e3fd7faef8555e1099547a82c" + }, + { + "type": "Feature", + "properties": { + "name": "Hol", + "longitude" : 52.4671021, + "latitude" : 16.927122 + }, + "geometry": { + "coordinates": [ + [ + [ + 16.926625, + 52.467294 + ], + [ + 16.926568, + 52.46719 + ], + [ + 16.927008, + 52.467108 + ], + [ + 16.926953, + 52.467024 + ], + [ + 16.927463, + 52.466919 + ], + [ + 16.927467, + 52.466956 + ], + [ + 16.927316, + 52.467153 + ], + [ + 16.926907, + 52.467235 + ], + [ + 16.926625, + 52.467294 + ] + ] + ], + "type": "Polygon" + }, + "id": "facdd5349991758b9ad99d4e123c91cc" + } + ], + "type": "FeatureCollection" +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java index 95dade8..8b39465 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java @@ -23,6 +23,7 @@ import android.widget.Button; import android.widget.TextView; import android.widget.Toast; +import com.annimon.stream.Stream; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.mapbox.android.core.permissions.PermissionsListener; import com.mapbox.android.core.permissions.PermissionsManager; @@ -50,15 +51,20 @@ import com.uam.wmi.findmytutor.service.CoordinateService; import com.uam.wmi.findmytutor.service.UserService; import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.RestApiHelper; +import com.uam.wmi.findmytutor.utils.SharingLevel; import com.uam.wmi.findmytutor.utils.mapUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.annotations.NonNull; import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Predicate; import io.reactivex.observers.DisposableSingleObserver; import io.reactivex.schedulers.Schedulers; import okhttp3.ResponseBody; @@ -71,6 +77,7 @@ import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE; 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.visibility; +import static java.util.stream.Collectors.toList; public class MapActivity extends BaseActivity @@ -237,6 +244,7 @@ public class MapActivity extends BaseActivity latLng.getLatitude(), latLng.getLongitude(), latLng.getAltitude(), + "approx", PrefUtils.getUserFirstName(getApplicationContext()) + " " + PrefUtils.getUserLastName(getApplicationContext()), PrefUtils.getUserId(getApplicationContext()), PrefUtils.getLocationLevel(getApplicationContext()) @@ -344,10 +352,11 @@ public class MapActivity extends BaseActivity private void fetchTopCoords() { disposable.add( - // coordinateService.getTopCoordinates() coordinateService.getOnlineCoordinates() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .map(tutors -> Stream.of(tutors). + filterNot(t -> t.getDisplayMode().equals(SharingLevel.PRESENCE.toString())).toList()) .subscribeWith(new DisposableSingleObserver>() { @Override @@ -374,7 +383,7 @@ public class MapActivity extends BaseActivity if (previousCoordsIds.isEmpty()) { previousCoordsIds.addAll(currentCoordsIds); } else { - // here we clear + it returns bool if smthing was removed + // here we clear + it returns bool if sth was removed if (previousCoordsIds.removeAll(currentCoordsIds)) { for (String toRemoveId : previousCoordsIds) { Log.e(tag + "delete: ", "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId)); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java index 839f673..38bff8d 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java @@ -19,6 +19,7 @@ import android.widget.Toast; import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.service.BackgroundLocalizationService; import com.uam.wmi.findmytutor.utils.PrefUtils; +import com.uam.wmi.findmytutor.utils.SharingLevel; import java.util.Arrays; import java.util.HashMap; @@ -40,9 +41,10 @@ public class SharingFragment extends PreferenceFragment { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); locationLevelMapping = new HashMap(); - locationLevelMapping.put(0,"presence"); - locationLevelMapping.put(1,"approximated"); - locationLevelMapping.put(2,"exact"); + + locationLevelMapping.put(0, SharingLevel.PRESENCE.toString()); + locationLevelMapping.put(1, SharingLevel.APPROXIMATED.toString()); + locationLevelMapping.put(2, SharingLevel.EXACT.toString()); addPreferencesFromResource(R.layout.pref_sharing); Preference manualStatus = findPreference("key_manual_status"); @@ -60,8 +62,8 @@ public class SharingFragment extends PreferenceFragment { }); locationMode.setOnPreferenceChangeListener((preference, newValue) -> { - ListPreference lp = (ListPreference) preference; PrefUtils.storeLocationMode(getApplicationContext(),locationLevelMapping.get(Integer.parseInt((String) newValue))); + return true; }); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java b/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java index 5c23701..9b9d580 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java @@ -44,15 +44,17 @@ public class Coordinate extends BaseResponse { @SerializedName("label") private String label; - public Coordinate (Double latitude, Double longitude, Double altitude, String label, String userId, String displayMode) { + public Coordinate (Double latitude, Double longitude, Double altitude, String approximatedLocation, String label, String userId, String displayMode) { //if (!latitudeRange.contains(latitude)) throw new IllegalArgumentException("Inappropriate latitude value" + latitude); //if (!longtitudeRange.contains(longitude)) throw new IllegalArgumentException("Inappropriate longitude value" + longitude); + //if (approximatedLocation == null) throw new IllegalArgumentException("Inappropriate approximatedLocation"); this.latitude = latitude; this.longitude = longitude; this.altitude = altitude; this.label = label; this.userId = userId; + this.approximatedLocation = approximatedLocation; this.displayMode = displayMode; } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java index 2b3ca3c..331e703 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java @@ -27,14 +27,18 @@ import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.tasks.OnSuccessListener; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; +import com.mapbox.geojson.Point; import com.uam.wmi.findmytutor.model.Coordinate; import com.uam.wmi.findmytutor.network.ApiClient; +import com.uam.wmi.findmytutor.utils.ApproximatedLocalization; +import com.uam.wmi.findmytutor.utils.Consts; import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.RestApiHelper; +import com.uam.wmi.findmytutor.utils.SharingLevel; +import com.uam.wmi.findmytutor.utils.mapUtils; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executor; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; @@ -43,6 +47,9 @@ import io.reactivex.schedulers.Schedulers; import okhttp3.ResponseBody; import timber.log.Timber; +import static com.uam.wmi.findmytutor.utils.Consts.presenceApproximatedName; +import static com.uam.wmi.findmytutor.utils.Consts.presenceLatitude; +import static com.uam.wmi.findmytutor.utils.Consts.presencelongitude; import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus; public class BackgroundLocalizationService extends Service { @@ -50,7 +57,6 @@ public class BackgroundLocalizationService extends Service { private static final String TAG = "MyLocationService"; private static final int LOCATION_INTERVAL = 1000; private static final float LOCATION_DISTANCE = 5f; - public static String str_receiver = "background.location.broadcast"; private static long notify_interval = 10000; Location mLastLocation; Boolean stopService = false; @@ -64,6 +70,7 @@ public class BackgroundLocalizationService extends Service { private Runnable mStatusChecker; private FusedLocationProviderClient mFusedLocationClient; + public BackgroundLocalizationService() { providers.add(LocationManager.GPS_PROVIDER); providers.add(LocationManager.NETWORK_PROVIDER); @@ -74,6 +81,7 @@ public class BackgroundLocalizationService extends Service { new LocationListener(LocationManager.NETWORK_PROVIDER), new LocationListener(LocationManager.PASSIVE_PROVIDER) }; + } @Override @@ -90,7 +98,7 @@ public class BackgroundLocalizationService extends Service { stopService = intent.getBooleanExtra("request_stop", false); } if (stopService) { - storeBackgroundLocationStatus(getApplication(),false); + storeBackgroundLocationStatus(getApplication(), false); stopForeground(true); stopSelf(); return START_STICKY; @@ -102,7 +110,7 @@ public class BackgroundLocalizationService extends Service { @Override public void onCreate() { Log.e(TAG, "onCreate"); - storeBackgroundLocationStatus(getApplication(),true); + storeBackgroundLocationStatus(getApplication(), true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startMyOwnForeground(); @@ -114,7 +122,6 @@ public class BackgroundLocalizationService extends Service { mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); - initializeLocationManager(); Integer providerIndex = 0; @@ -137,7 +144,7 @@ public class BackgroundLocalizationService extends Service { providerIndex++; } - if(!stopService){ + if (!stopService) { mStatusChecker = () -> { try { fn_getlocation(); @@ -202,20 +209,12 @@ public class BackgroundLocalizationService extends Service { Log.e("Best localization:", String.valueOf(bestLocation)); - /* if (bestLocation != null) - fn_update(bestLocation); -*/ - mFusedLocationClient.getLastLocation().addOnSuccessListener( - new OnSuccessListener() { - @Override - public void onSuccess(Location location) { - if (location != null) { - mLastLocation = location; - fn_update(location); - } + location -> { + if (location != null) { + mLastLocation = location; + fn_update(location); } - }); } @@ -283,11 +282,13 @@ public class BackgroundLocalizationService extends Service { } } + @SuppressLint("StaticFieldLeak") private class Task extends AsyncTask { + ApproximatedLocalization approximatedLocalization; private Double latitude; private Double longitude; private Double altitude; - + private String approximatedBuildingPart = null; private CompositeDisposable disposable = new CompositeDisposable(); private CoordinateService coordinateService = ApiClient.getClient(getApplicationContext()) .create(CoordinateService.class); @@ -296,16 +297,30 @@ public class BackgroundLocalizationService extends Service { latitude = location.getLatitude(); longitude = location.getLongitude(); altitude = location.getAltitude(); + approximatedLocalization = new ApproximatedLocalization(mapUtils.loadJsonFromAsset(getApplicationContext(), "building.geojson")); + approximatedBuildingPart = approximatedLocalization.getNameOfBuildingPart(Point.fromLngLat(longitude, latitude)); } @Override protected Object doInBackground(Object[] objects) { + if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.PRESENCE.toString())) { + latitude = presenceLatitude; + longitude = presencelongitude; + approximatedBuildingPart = presenceApproximatedName; + } else if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.APPROXIMATED.toString())) { + List points = approximatedLocalization.getMiddlePointOfBuildingPart(approximatedBuildingPart); + + latitude = points.get(0); + longitude = points.get(1); + } + try { Coordinate coordinate = new Coordinate( latitude, longitude, altitude, + approximatedBuildingPart, PrefUtils.getUserStatus(getApplicationContext()), PrefUtils.getUserId(getApplicationContext()), PrefUtils.getLocationLevel(getApplicationContext()) diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java new file mode 100644 index 0000000..4a42bf3 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java @@ -0,0 +1,69 @@ +package com.uam.wmi.findmytutor.utils; + +import android.support.annotation.NonNull; + +import com.google.gson.GsonBuilder; +import com.mapbox.geojson.BoundingBox; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; +import com.mapbox.geojson.Point; +import com.mapbox.geojson.Polygon; +import com.mapbox.geojson.gson.BoundingBoxDeserializer; +import com.mapbox.geojson.gson.GeoJsonAdapterFactory; +import com.mapbox.geojson.gson.GeometryDeserializer; +import com.mapbox.geojson.gson.PointDeserializer; +import com.mapbox.turf.TurfJoins; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +; + +public class ApproximatedLocalization { + private FeatureCollection buildingSchema = null; + + public ApproximatedLocalization(String buildingObject) { + buildingSchema = fromJson(buildingObject); + } + + private FeatureCollection fromJson(@NonNull String json) { + GsonBuilder gson = new GsonBuilder(); + + gson.registerTypeAdapterFactory(GeoJsonAdapterFactory.create()); + gson.registerTypeAdapter(Point.class, new PointDeserializer()); + gson.registerTypeAdapter(Geometry.class, new GeometryDeserializer()); + gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer()); + + return gson.create().fromJson(json, FeatureCollection.class); + } + + public String getNameOfBuildingPart(Point point) { + + for (Feature feature : Objects.requireNonNull(buildingSchema.features())) { + boolean isInside = TurfJoins.inside(point, (Polygon) Objects.requireNonNull(feature.geometry())); + + if (isInside) + return Objects.requireNonNull(Objects.requireNonNull(feature.getStringProperty("name"))); + } + + return null; + } + + public List getMiddlePointOfBuildingPart(String buildingPart) { + + for (Feature feature : Objects.requireNonNull(buildingSchema.features())) { + String partName = feature.getStringProperty("name"); + + if (buildingPart != null && buildingPart.equals(partName)) { + Double longitude = feature.getNumberProperty("longitude").doubleValue(); + Double latitude = feature.getNumberProperty("latitude").doubleValue(); + + return Arrays.asList(longitude, latitude); + } + } + + return Arrays.asList(0.0, 0.0); + } +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java new file mode 100644 index 0000000..eef58b5 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java @@ -0,0 +1,7 @@ +package com.uam.wmi.findmytutor.utils; + +public class Consts { + public final static Double presenceLatitude = 52.467491; + public final static Double presencelongitude = 16.926782; + public final static String presenceApproximatedName = "unknown"; +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java new file mode 100644 index 0000000..055651b --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java @@ -0,0 +1,18 @@ +package com.uam.wmi.findmytutor.utils; + +public enum SharingLevel { + PRESENCE("presence"), + APPROXIMATED("approximated"), + EXACT("exact"); + + private final String text; + + SharingLevel(final String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java index 10a651b..9dcdd1e 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java @@ -6,6 +6,7 @@ import android.graphics.Color; import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; +import android.content.res.AssetManager; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.PolygonOptions; diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index efbf417..be1a4f3 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,19 +1,17 @@ - @color/mapboxGray - @color/mapboxGrayDark10 - @color/mapboxPink - #cf5e5e + #476483 + #3A3553 + #CF0E0F + #89c3c3c3 #89c3c3c3 #858585 #232323 - #d1e200f6 #ffffff #80ffffff - #F5F5F5 #dfdfdf