diff --git a/collect_app/src/main/AndroidManifest.xml b/collect_app/src/main/AndroidManifest.xml index 82c71c684..ded0697d0 100644 --- a/collect_app/src/main/AndroidManifest.xml +++ b/collect_app/src/main/AndroidManifest.xml @@ -109,7 +109,7 @@ - + @@ -373,5 +373,6 @@ + diff --git a/collect_app/src/main/java/org/fieldsight/naxa/project/MapActivity.java b/collect_app/src/main/java/org/fieldsight/naxa/project/MapActivity.java deleted file mode 100644 index 00b513d6d..000000000 --- a/collect_app/src/main/java/org/fieldsight/naxa/project/MapActivity.java +++ /dev/null @@ -1,548 +0,0 @@ -//package org.fieldsight.naxa.PROJECT;/* -// * Copyright (C) 2016 GeoODK -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except -// * in compliance with the License. You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software distributed under the License -// * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express -// * or implied. See the License for the specific language governing permissions and limitations under -// * the License. -// */ -// -// -//import android.app.AlertDialog; -//import android.content.Context; -//import android.content.DialogInterface; -//import android.content.Intent; -//import android.location.Location; -//import android.os.Bundle; -//import android.os.Handler; -//import android.provider.Settings; -//import android.view.View; -//import android.view.Window; -//import android.widget.Button; -//import android.widget.ImageButton; -//import android.widget.TextView; -// -//import androidx.appcompat.widget.Toolbar; -//import androidx.core.content.ContextCompat; -// -//import com.google.android.gms.location.LocationListener; -// -//import org.fieldsight.collect.android.R; -//import org.odk.collect.android.spatial.MapHelper; -//import org.fieldsight.naxa.login.model.Site; -//import org.odk.collect.android.activities.CollectAbstractActivity; -//import org.odk.collect.android.location.client.LocationClient; -//import org.odk.collect.android.location.client.LocationClients; -//import org.odk.collect.android.utilities.GeoPointUtils; -//import org.odk.collect.android.utilities.ToastUtils; -//import org.osmdroid.events.MapEventsReceiver; -//import org.osmdroid.tileprovider.IRegisterReceiver; -//import org.osmdroid.util.GeoPoint; -//import org.osmdroid.views.MapView; -//import org.osmdroid.views.overlay.MapEventsOverlay; -//import org.osmdroid.views.overlay.Marker; -//import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; -// -//import java.text.DecimalFormat; -// -//import timber.log.Timber; -// -//import static org.fieldsight.naxa.common.Constant.EXTRA_OBJECT; -//import static org.odk.collect.android.utilities.PermissionUtils.checkIfLocationPermissionsGranted; -// -// -///** -// * Version of the GeoPointMapActivity that uses the new OSMDDroid -// * -// * @author jonnordling@gmail.com -// */ -//public class MapActivity extends CollectAbstractActivity implements LocationListener, -// Marker.OnMarkerDragListener, MapEventsReceiver, IRegisterReceiver, -// LocationClient.LocationClientListener { -// -// private static final String LOCATION_COUNT = "locationCount"; -// -// //private GoogleMap map; -// private MapView map; -// -// private final Handler handler = new Handler(); -// private Marker marker; -// -// private GeoPoint latLng; -// -// private TextView locationStatus; -// -// private LocationClient locationClient; -// -// private Location location; -// -// -// private boolean captureLocation; -// private boolean setClear; -// private boolean isDragged; -// private ImageButton showLocationButton; -// -// private int locationCount = 0; -// -// private MapHelper helper; -// -// private AlertDialog zoomDialog; -// private View zoomDialogView; -// -// private Button zoomPointButton; -// private Button zoomLocationButton; -// -// public MyLocationNewOverlay myLocationOverlay; -// -// private boolean readOnly; -// private boolean draggable; -// private boolean intentDraggable; -// private boolean locationFromIntent; -// private int locationCountNum = 0; -// private boolean foundFirstLocation; -// private Site loadedSite; -// private Toolbar toolbar; -// private GeoPoint siteGeoPoint; -// -// -// public static void start(Context context, Site loadedSite) { -// -// -// Intent intent = new Intent(context, MapActivity.class); -// intent.putExtra(EXTRA_OBJECT, loadedSite); -// context.startActivity(intent); -// -// } -// -// -// @Override -// protected void onCreate(Bundle savedInstanceState) { -// super.onCreate(savedInstanceState); -// requestWindowFeature(Window.FEATURE_NO_TITLE); -// -// if (!checkIfLocationPermissionsGranted(this)) { -// finish(); -// return; -// } -// -// if (savedInstanceState != null) { -// locationCount = savedInstanceState.getInt(LOCATION_COUNT); -// } -// -// try { -// setContentView(R.layout.activity_map); -// } catch (NoClassDefFoundError e) { -// ToastUtils.showShortToast(R.string.google_play_services_error_occured); -// finish(); -// return; -// } -// -// map = findViewById(R.id.omap); -//// if (helper == null) { -//// // For testing: -//// helper = new MapHelper(this, map, this); -//// -//// map.setMultiTouchControls(true); -//// map.setBuiltInZoomControls(true); -//// map.setTilesScaledToDpi(true); -//// } -// -// marker = new Marker(map); -// -// toolbar = findViewById(R.id.toolbar); -// setupToolbar(); -// setSiteMarkerOrFail(); -// -// -// marker.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_place_black)); -// myLocationOverlay = new MyLocationNewOverlay(map); -// -// -// locationStatus = findViewById(R.id.location_status); -// locationStatus.setText(getString(R.string.please_wait_long)); -// -// -// locationClient = LocationClients.clientForContext(this); -// locationClient.setListener(this); -// -// -// -// // Focuses on marked location -// showLocationButton = findViewById(R.id.show_location); -// showLocationButton.setVisibility(View.VISIBLE); -// showLocationButton.setEnabled(false); -// showLocationButton.setOnClickListener(new View.OnClickListener() { -// @Override -// public void onClick(View v) { -// -// showZoomDialog(); -// } -// }); -// -// // not clickable until we have a marker set.... -// showLocationButton.setClickable(false); -// -// // Menu Layer Toggle -// ImageButton layersButton = findViewById(R.id.layer_menu); -// layersButton.setOnClickListener(new View.OnClickListener() { -// @Override -// public void onClick(View v) { -// helper.showLayersDialog(); -// -// } -// }); -// -// -//// zoomDialogView = getLayoutInflater().inflate(R.layout.geo_zoom_dialog, null); -//// -//// zoomLocationButton = zoomDialogView.findViewById(R.id.zoom_location); -//// zoomLocationButton.setOnClickListener(new View.OnClickListener() { -//// @Override -//// public void onClick(View v) { -//// zoomToLocation(); -//// map.invalidate(); -//// zoomDialog.dismiss(); -//// } -//// }); -//// -//// zoomPointButton = zoomDialogView.findViewById(R.id.zoom_saved_location); -//// zoomPointButton.setText("Zoom to site"); -//// zoomPointButton.setOnClickListener(new View.OnClickListener() { -//// -//// @Override -//// public void onClick(View v) { -//// zoomToPoint(); -//// map.invalidate(); -//// zoomDialog.dismiss(); -//// } -//// }); -//// -//// -//// if (latLng != null) { -//// marker.setPosition(latLng); -//// map.getOverlays().add(marker); -//// map.invalidate(); -//// captureLocation = true; -//// foundFirstLocation = true; -//// zoomToPoint(); -//// } -// } -// -// private void setSiteMarkerOrFail() { -// Bundle bundle = getIntent().getExtras(); -// -// -// if (bundle != null) { -// loadedSite = bundle.getParcelable(EXTRA_OBJECT); -// getSupportActionBar().setTitle(loadedSite.getName()); -// handler.postDelayed(new Runnable() { -// public void run() { -// -// try { -// siteGeoPoint = new GeoPoint(Double.parseDouble(loadedSite.getLatitude()), Double.parseDouble(loadedSite.getLongitude())); -// map.getController().setZoom(4); -// map.getController().setCenter(siteGeoPoint); -// marker.setTitle(loadedSite.getName()); -// marker.setSnippet(loadedSite.getAddress()); -// marker.setPosition(siteGeoPoint); -// map.getOverlays().add(marker); -// -// } catch (NumberFormatException e) { -// ToastUtils.showShortToastInMiddle("Failed to load site marker"); -// } -// } -// }, 100); -// } -// } -// -// private void setupToolbar() { -// setSupportActionBar(toolbar); -// getSupportActionBar().setDisplayShowHomeEnabled(true); -// getSupportActionBar().setDisplayHomeAsUpEnabled(true); -// getSupportActionBar().setTitle(R.string.projects); -// } -// -// -// @Override -// protected void onSaveInstanceState(Bundle outState) { -// super.onSaveInstanceState(outState); -// outState.putInt(LOCATION_COUNT, locationCount); -// } -// -// @Override -// protected void onStart() { -// super.onStart(); -// locationClient.start(); -// } -// -// @Override -// protected void onResume() { -// super.onResume(); -// -// if (map != null) { -// helper.setBasemap(); -// } -// -// } -// -// @Override -// protected void onStop() { -// locationClient.stop(); -// super.onStop(); -// } -// -// -// private void upMyLocationOverlayLayers() { -// showLocationButton.setClickable(marker != null); -// -// // make sure we have a good location provider before continuing -// locationClient.requestLocationUpdates(this); -// -// if (!locationClient.isLocationAvailable()) { -// showGPSDisabledAlertToUser(); -// -// } else { -// overlayMyLocationLayers(); -// } -// } -// -// private void overlayMyLocationLayers() { -// map.getOverlays().add(myLocationOverlay); -// if (draggable && !readOnly) { -// if (marker != null) { -// marker.setOnMarkerDragListener(this); -// marker.setDraggable(true); -// } -// -// MapEventsOverlay overlayEvents = new MapEventsOverlay(this); -// map.getOverlays().add(overlayEvents); -// } -// -// myLocationOverlay.setEnabled(true); -// myLocationOverlay.enableMyLocation(); -// } -// -// private void zoomToPoint() { -// if (siteGeoPoint != null) { -// handler.postDelayed(new Runnable() { -// public void run() { -// map.getController().setZoom(16); -// map.getController().setCenter(siteGeoPoint); -// map.invalidate(); -// } -// }, 200); -// } -// -// } -// -// -// private String truncateFloat(float f) { -// return new DecimalFormat("#.##").format(f); -// } -// -// -// @Override -// public void onLocationChanged(Location location) { -// -// this.location = location; -// -// if (this.location != null) { -// int locationCountFoundLimit = 1; -// if (locationCountNum >= locationCountFoundLimit) { -// showLocationButton.setEnabled(true); -// if (!captureLocation & !setClear) { -// latLng = new GeoPoint(this.location.getLatitude(), this.location.getLongitude()); -// captureLocation = true; -// } -// if (!foundFirstLocation) { -// // zoomToPoint(); -// showZoomDialog(); -// foundFirstLocation = true; -// } -// locationStatus.setText( -// getString(R.string.location_provider_accuracy, GeoPointUtils.capitalizeGps(this.location.getProvider()), -// truncateFloat(this.location.getAccuracy()))); -// } else { -// // Prevent from forever increasing -// if (locationCountNum <= 100) { -// locationCountNum++; -// } -// } -// -// -// //if (location.getLatitude() != marker.getPosition().getLatitude() & location -// // .getLongitude() != marker.getPosition().getLongitude()) { -// //reloadLocationButton.setEnabled(true); -// //} -// // -// //If location is accurate enough, stop updating position and make the marker -// // draggable -// //if (location.getAccuracy() <= mLocationAccuracy) { -// //stopGeolocating(); -// //} -// -// } else { -// Timber.i("onLocationChanged(%d) null location", locationCount); -// } -// } -// -// @Override -// public void onMarkerDrag(Marker arg0) { -// -// } -// -// @Override -// public void onMarkerDragEnd(Marker marker) { -// latLng = marker.getPosition(); -// isDragged = true; -// captureLocation = true; -// setClear = false; -// map.getController().animateTo(latLng); -// map.getController().setZoom(map.getZoomLevel()); -// } -// -// @Override -// public void onMarkerDragStart(Marker arg0) { -// //stopGeolocating(); -// } -// -// @Override -// public boolean singleTapConfirmedHelper(GeoPoint geoPoint) { -// return false; -// } -// -// @Override -// public boolean longPressHelper(GeoPoint geoPoint) { -// if (marker == null) { -// marker = new Marker(map); -// -// } -// showLocationButton.setEnabled(true); -// map.invalidate(); -// marker.setPosition(geoPoint); -// marker.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_place_black)); -// marker.setDraggable(true); -// latLng = geoPoint; -// isDragged = true; -// setClear = false; -// captureLocation = true; -// map.getOverlays().add(marker); -// return false; -// } -// -// public void showZoomDialog() { -// -//// if (zoomDialog == null) { -//// AlertDialog.Builder builder = new AlertDialog.Builder(this); -//// builder.setTitle(getString(R.string.zoom_to_where)); -//// builder.setView(zoomDialogView) -//// .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { -//// public void onClick(DialogInterface dialog, int id) { -//// dialog.cancel(); -//// } -//// }) -//// .setOnCancelListener(new DialogInterface.OnCancelListener() { -//// @Override -//// public void onCancel(DialogInterface dialog) { -//// dialog.cancel(); -//// zoomDialog.dismiss(); -//// } -//// }); -//// zoomDialog = builder.create(); -//// } -//// //If feature enable zoom to button else disable -//// if (myLocationOverlay.getMyLocation() != null) { -//// zoomLocationButton.setEnabled(true); -//// zoomLocationButton.setBackgroundColor(Color.parseColor("#50cccccc")); -//// zoomLocationButton.setTextColor(themeUtils.getPrimaryTextColor()); -//// } else { -//// zoomLocationButton.setEnabled(false); -//// zoomLocationButton.setBackgroundColor(Color.parseColor("#50e2e2e2")); -//// zoomLocationButton.setTextColor(Color.parseColor("#FF979797")); -//// } -//// -//// if (latLng != null & !setClear) { -//// zoomPointButton.setEnabled(true); -//// zoomPointButton.setBackgroundColor(Color.parseColor("#50cccccc")); -//// zoomPointButton.setTextColor(themeUtils.getPrimaryTextColor()); -//// } else { -//// zoomPointButton.setEnabled(false); -//// zoomPointButton.setBackgroundColor(Color.parseColor("#50e2e2e2")); -//// zoomPointButton.setTextColor(Color.parseColor("#FF979797")); -//// } -//// zoomDialog.show(); -// } -// -// private void zoomToLocation() { -// if (myLocationOverlay.getMyLocation() != null) { -// final GeoPoint location = new GeoPoint(this.location.getLatitude(), -// this.location.getLongitude()); -// handler.postDelayed(new Runnable() { -// public void run() { -// map.getController().setZoom(16); -// map.getController().setCenter(location); -// map.invalidate(); -// } -// }, 200); -// } -// } -// -// private void showGPSDisabledAlertToUser() { -// AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); -// alertDialogBuilder.setMessage(getString(R.string.gps_enable_message)) -// .setCancelable(false) -// .setPositiveButton(getString(R.string.enable_gps), -// new DialogInterface.OnClickListener() { -// public void onClick(DialogInterface dialog, int id) { -// startActivityForResult( -// new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0); -// } -// }); -// alertDialogBuilder.setNegativeButton(getString(R.string.cancel), -// new DialogInterface.OnClickListener() { -// public void onClick(DialogInterface dialog, int id) { -// dialog.cancel(); -// } -// }); -// AlertDialog alert = alertDialogBuilder.create(); -// alert.show(); -// } -// -// @Override -// public void destroy() { -// -// } -// -// @Override -// public void onClientStart() { -// upMyLocationOverlayLayers(); -// } -// -// @Override -// public void onClientStartFailure() { -// showGPSDisabledAlertToUser(); -// } -// -// @Override -// public void onClientStop() { -// -// } -// -// public AlertDialog getZoomDialog() { -// return zoomDialog; -// } -// -// /** -// * For testing purposes. -// * -// * @param helper The MapHelper to set. -// */ -// public void setHelper(MapHelper helper) { -// this.helper = helper; -// } -//} diff --git a/collect_app/src/main/java/org/fieldsight/naxa/project/ProjectMapActivity.java b/collect_app/src/main/java/org/fieldsight/naxa/project/ProjectMapActivity.java new file mode 100644 index 000000000..d65ff3abe --- /dev/null +++ b/collect_app/src/main/java/org/fieldsight/naxa/project/ProjectMapActivity.java @@ -0,0 +1,68 @@ +package org.fieldsight.naxa.project; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.appcompat.widget.Toolbar; + +import org.fieldsight.collect.android.R; +import org.fieldsight.naxa.login.model.Site; +import org.fieldsight.naxa.site.map.ProjectMapFragment; +import org.odk.collect.android.activities.CollectAbstractActivity; +import org.odk.collect.android.utilities.ToastUtils; + +import static org.fieldsight.naxa.common.Constant.EXTRA_OBJECT; + + +public class ProjectMapActivity extends CollectAbstractActivity { + + + private Toolbar toolbar; + + public static void start(Context context, Site loadedSite) { + Intent intent = new Intent(context, ProjectMapActivity.class); + intent.putExtra(EXTRA_OBJECT, loadedSite); + context.startActivity(intent); + } + + + private void setupToolbar() { + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayShowTitleEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_site_map); + setupToolbar(); + Site loadedSite = getIntent().getExtras().getParcelable(EXTRA_OBJECT); + if (loadedSite == null) { + ToastUtils.showLongToast(R.string.dialog_unexpected_error_title); + finish(); + return; + } + + getSupportFragmentManager() + .beginTransaction() + .add(R.id.fragment_container, ProjectMapFragment.newInstance(loadedSite), "frag1") + .commit(); + + toolbar.setTitle(loadedSite.getName()); + + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/FragmentHostActivity.java b/collect_app/src/main/java/org/fieldsight/naxa/site/FragmentHostActivity.java index 41019835c..0af665262 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/FragmentHostActivity.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/FragmentHostActivity.java @@ -98,8 +98,6 @@ private void setupToolbar() { private void bindUI() { toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - } @Override diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectDashboardActivity.java b/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectDashboardActivity.java index b80b5bc91..1cbcbfe7a 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectDashboardActivity.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectDashboardActivity.java @@ -67,11 +67,10 @@ import org.fieldsight.naxa.profile.UserActivity; import org.fieldsight.naxa.project.TermsLabels; import org.fieldsight.naxa.site.db.SiteLocalSource; +import org.fieldsight.naxa.site.map.ProjectMapFragment; import org.fieldsight.naxa.v3.network.SyncActivity; import org.json.JSONObject; import org.odk.collect.android.activities.FileManagerTabs; -import org.odk.collect.android.fragments.OsmMapFragment; -import org.odk.collect.android.geo.MapProvider; import org.odk.collect.android.utilities.ApplicationConstants; import org.odk.collect.android.utilities.ToastUtils; diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/SiteDashboardFragment.java b/collect_app/src/main/java/org/fieldsight/naxa/site/SiteDashboardFragment.java index 9c9f8c72f..9bb40890f 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/SiteDashboardFragment.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/SiteDashboardFragment.java @@ -36,9 +36,9 @@ import org.fieldsight.naxa.common.utilities.SnackBarUtils; import org.fieldsight.naxa.forms.ui.FieldSightFormListFragment; import org.fieldsight.naxa.login.model.Site; +import org.fieldsight.naxa.project.ProjectMapActivity; import org.fieldsight.naxa.site.db.SiteLocalSource; import org.fieldsight.naxa.site.db.SiteRemoteSource; -import org.fieldsight.naxa.site.map.FieldSightMapActivity; import org.fieldsight.naxa.sitedocuments.SiteDocumentsListActivity; import org.fieldsight.naxa.stages.StageListFragment; import org.odk.collect.android.SiteProfileActivity; @@ -243,7 +243,7 @@ private void checkPermissionAndOpenMap() { new PermissionUtils().requestLocationPermissions(requireActivity(), new PermissionListener() { @Override public void granted() { - FieldSightMapActivity.start(getActivity(), loadedSite); + ProjectMapActivity.start(getActivity(), loadedSite); } @@ -253,7 +253,7 @@ public void denied() { } }); } else { - FieldSightMapActivity.start(getActivity(), loadedSite); + ProjectMapActivity.start(getActivity(), loadedSite); } } diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/db/SiteLocalSource.java b/collect_app/src/main/java/org/fieldsight/naxa/site/db/SiteLocalSource.java index e8f073679..79368ab9e 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/db/SiteLocalSource.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/db/SiteLocalSource.java @@ -5,11 +5,11 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import org.odk.collect.android.application.Collect; import org.fieldsight.naxa.common.BaseLocalDataSource; import org.fieldsight.naxa.common.Constant; import org.fieldsight.naxa.common.FieldSightDatabase; import org.fieldsight.naxa.login.model.Site; +import org.odk.collect.android.application.Collect; import java.util.ArrayList; import java.util.List; diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/map/FieldSightMapActivity.java b/collect_app/src/main/java/org/fieldsight/naxa/site/map/FieldSightMapActivity.java index d5857649b..020d83761 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/map/FieldSightMapActivity.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/map/FieldSightMapActivity.java @@ -19,6 +19,7 @@ import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; +import android.util.SparseArray; import android.view.Window; import android.widget.ImageButton; @@ -37,19 +38,17 @@ import org.odk.collect.android.utilities.GeoUtils; import org.odk.collect.android.utilities.ToastUtils; import org.odk.collect.android.widgets.GeoPointWidget; -import org.osmdroid.util.BoundingBox; -import org.osmdroid.util.GeoPoint; import java.text.DecimalFormat; +import java.util.HashMap; import java.util.List; import io.reactivex.Observable; -import io.reactivex.SingleObserver; +import io.reactivex.ObservableSource; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.functions.Function; -import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; import timber.log.Timber; @@ -81,7 +80,7 @@ public class FieldSightMapActivity extends BaseGeoMapActivity { private int featureId = -1; // will be a positive featureId once map is ready - private FieldSightMapPoint location; + private MapPoint location; private boolean isDragged; @@ -127,6 +126,8 @@ public static void start(Context context, Site loadedSite) { } + private HashMap featureIdAndSite = new HashMap<>(); + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -155,7 +156,6 @@ public void onCreate(Bundle savedInstanceState) { .addTo(this, R.id.map_container, this::initMap, this::finish); - } @Override @@ -241,7 +241,7 @@ public void initMap(MapFragment newMapFragment) { } -// map.setGpsLocationListener(this::onLocationChanged); + map.setGpsLocationListener(this::onLocationChanged); map.setGpsLocationEnabled(true); if (previousState != null) { @@ -252,54 +252,59 @@ public void initMap(MapFragment newMapFragment) { map.setClickListener(new MapFragment.PointListener() { @Override public void onPoint(@NonNull MapPoint point) { - ToastUtils.showLongToast("Hi"); + String index = point.lat + ":" + point.lon; + ToastUtils.showLongToast(featureIdAndSite.get(index).getName()); } }); } private void loadSites(String projectId) { - SiteLocalSource.getInstance().getById(projectId).observe(this, sites -> { - Timber.i("Plotting %d sites on map", sites.size()); - Observable.just(sites) - .subscribeOn(Schedulers.computation()) - .observeOn(AndroidSchedulers.mainThread()) - .flatMapIterable((Function, Iterable>) sites1 -> sites1) - .filter(site -> !TextUtils.isEmpty(site.getLatitude()) - && !TextUtils.isEmpty(site.getLatitude())) - .map(new Function() { - @Override - public FieldSightMapPoint apply(Site site) { - Timber.i("prep Adding %s",site.getName()); - return new FieldSightMapPoint(site, site.getLatitude(), site.getLongitude()); - } - }) - .doOnNext(new Consumer() { - @Override - public void accept(FieldSightMapPoint fieldSightMapPoint) { - Timber.i("Adding %s",fieldSightMapPoint.getSite().getName()); - placeMarker(fieldSightMapPoint); - - } - }) - - .subscribe(new DisposableObserver() { - @Override - public void onNext(FieldSightMapPoint fieldSightMapPoint) { - Timber.i("Adding thoriwng %s",fieldSightMapPoint.getSite().getName()); - } - - @Override - public void onError(Throwable e) { - Timber.e(e); - } - - @Override - public void onComplete() { - - } - }); - }); + Disposable disposable = SiteLocalSource.getInstance().getByIdAsSingle(projectId) + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable disposable) throws Exception { + featureIdAndSite.clear(); + } + }) + .flattenAsObservable(new Function, Iterable>() { + @Override + public Iterable apply(List sites) throws Exception { + return sites; + } + }) + .filter(site -> !TextUtils.isEmpty(site.getLatitude()) + && !TextUtils.isEmpty(site.getLatitude())) + .flatMap(new Function>() { + @Override + public ObservableSource apply(Site site) throws Exception { + MapPoint mapPoint = new MapPoint(Double.parseDouble(site.getLatitude()), + Double.parseDouble(site.getLongitude())); + return Observable.just(mapPoint) + .doOnNext(new Consumer() { + @Override + public void accept(MapPoint mapPoint) throws Exception { + featureId = placeMarker(mapPoint); + featureIdAndSite.put(mapPoint.lat + ":" + mapPoint.lon, site); + } + }); + } + }).subscribe(new Consumer() { + @Override + public void accept(Object o) throws Exception { + + } + + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Timber.e(throwable); + } + }); + + } protected void restoreFromInstanceState(Bundle state) { @@ -313,7 +318,7 @@ protected void restoreFromInstanceState(Bundle state) { isPointLocked = state.getBoolean(IS_POINT_LOCKED_KEY, false); // Restore the marker and dialog after the flags, because they use some of them. - FieldSightMapPoint point = state.getParcelable(POINT_KEY); + MapPoint point = state.getParcelable(POINT_KEY); if (point != null) { placeMarker(point); } else { @@ -343,10 +348,10 @@ protected void restoreFromInstanceState(Bundle state) { } - public void onLocationChanged(FieldSightMapPoint point) { + public void onLocationChanged(MapPoint point) { - FieldSightMapPoint previousLocation = this.location; + MapPoint previousLocation = this.location; this.location = point; if (point != null) { @@ -390,7 +395,6 @@ public void onDragEnd(int draggedFeatureId) { } - private void enableZoomButton(boolean shouldEnable) { if (zoomButton != null) { zoomButton.setEnabled(shouldEnable); @@ -411,8 +415,9 @@ private void clear() { setClear = true; } - private void placeMarker(FieldSightMapPoint point) { + private int placeMarker(MapPoint point) { featureId = map.addMarker(point, intentDraggable && !intentReadOnly && !isPointLocked); + return featureId; } public void setCaptureLocation(boolean captureLocation) { diff --git a/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectMapFragment.java b/collect_app/src/main/java/org/fieldsight/naxa/site/map/ProjectMapFragment.java similarity index 64% rename from collect_app/src/main/java/org/fieldsight/naxa/site/ProjectMapFragment.java rename to collect_app/src/main/java/org/fieldsight/naxa/site/map/ProjectMapFragment.java index 08ffd5395..673e8aea6 100644 --- a/collect_app/src/main/java/org/fieldsight/naxa/site/ProjectMapFragment.java +++ b/collect_app/src/main/java/org/fieldsight/naxa/site/map/ProjectMapFragment.java @@ -1,6 +1,7 @@ -package org.fieldsight.naxa.site; +package org.fieldsight.naxa.site.map; import android.os.Bundle; +import android.os.Handler; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -11,8 +12,11 @@ import org.fieldsight.collect.android.R; import org.fieldsight.naxa.login.model.Project; import org.fieldsight.naxa.login.model.Site; +import org.fieldsight.naxa.site.SiteInfoWindow; +import org.fieldsight.naxa.site.SiteMarker; import org.fieldsight.naxa.site.db.SiteLocalSource; import org.odk.collect.android.fragments.OsmMapFragment; +import org.odk.collect.android.utilities.ToastUtils; import org.osmdroid.events.MapEventsReceiver; import org.osmdroid.util.BoundingBox; import org.osmdroid.util.GeoPoint; @@ -26,8 +30,8 @@ import io.reactivex.SingleObserver; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; import io.reactivex.functions.Function; +import io.reactivex.functions.Predicate; import io.reactivex.schedulers.Schedulers; import timber.log.Timber; @@ -37,6 +41,7 @@ public class ProjectMapFragment extends OsmMapFragment { private Project loadedProject; private MapView map; + private Site loadedSite; public static ProjectMapFragment newInstance(Project project) { Bundle bundle = new Bundle(); @@ -46,6 +51,15 @@ public static ProjectMapFragment newInstance(Project project) { return siteListFragment; } + + public static ProjectMapFragment newInstance(Site site) { + Bundle bundle = new Bundle(); + bundle.putParcelable(EXTRA_OBJECT, site); + ProjectMapFragment siteListFragment = new ProjectMapFragment(); + siteListFragment.setArguments(bundle); + return siteListFragment; + } + private void loadSites(String projectId) { SiteLocalSource.getInstance().getById(projectId).observe(requireActivity(), sites -> { Timber.i("Plotting %d sites on map", sites.size()); @@ -53,8 +67,16 @@ private void loadSites(String projectId) { .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .flatMapIterable((Function, Iterable>) sites1 -> sites1) - .filter(site -> !TextUtils.isEmpty(site.getLatitude()) - && !TextUtils.isEmpty(site.getLatitude())) + .filter(new Predicate() { + @Override + public boolean test(Site site) throws Exception { + boolean cantParseLocation = TextUtils.isEmpty(site.getLatitude()) + && TextUtils.isEmpty(site.getLatitude()); + boolean isBadValue = TextUtils.equals(site.getLatitude(), "0") && + TextUtils.equals(site.getLongitude(), "0"); + return !cantParseLocation && !isBadValue; + } + }) .doOnNext(site -> map.getOverlays().add(mapSiteToMarker(site))) .map(site -> new GeoPoint(Double.parseDouble(site.getLatitude()), Double.parseDouble(site.getLongitude()))) @@ -98,6 +120,8 @@ public boolean longPressHelper(GeoPoint p) { } + private Handler handler = new Handler(); + private SiteMarker mapSiteToMarker(Site site) { GeoPoint geoPoint = new GeoPoint(Double.parseDouble(site.getLatitude()), Double.parseDouble(site.getLongitude())); SiteMarker marker = getMarker(geoPoint, site.getName(), site.getAddress()); @@ -105,8 +129,14 @@ private SiteMarker mapSiteToMarker(Site site) { marker.setSite(site); marker.setInfoWindow(infoWindow); marker.setSubDescription(site.getId()); + marker.setOnMarkerClickListener((marker1, mapView) -> { + InfoWindow.closeAllInfoWindowsOn(map); + mapView.getController().animateTo(marker1.getPosition()); + handler.postDelayed(marker1::showInfoWindow, 500); + return true; + }); - return marker; + return marker; } @@ -114,20 +144,48 @@ private SiteMarker getMarker(GeoPoint geoPoint, String title, String snippet) { SiteMarker marker = new SiteMarker(map); marker.setSnippet(snippet); marker.setTitle(title); - marker.setIcon(ContextCompat.getDrawable(requireContext(), R.drawable.ic_place_black)); + marker.setIcon(ContextCompat.getDrawable(requireContext(), R.drawable.ic_place_blue)); marker.setPosition(geoPoint); return marker; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - loadedProject = getArguments().getParcelable(EXTRA_OBJECT); + Object obj = getArguments().getParcelable(EXTRA_OBJECT); + if (obj instanceof Project) { + loadedProject = (Project) obj; + } else if (obj instanceof Site) { + loadedSite = (Site) obj; + } + getMapAsync(map -> { ProjectMapFragment.this.map = map; setupInfoDialogSettings(); - String projectId = loadedProject.getId(); - loadSites(projectId); + + map.setMinZoomLevel(3); + + if (loadedProject != null) { + String projectId = loadedProject.getId(); + loadSites(projectId); + } else if (loadedSite != null) { + SiteMarker marker = mapSiteToMarker(loadedSite); + map.getOverlays().add(marker); + + map.getController().zoomTo(15); + + + handler.postDelayed(new Runnable() { + @Override + public void run() { + map.getController().animateTo(marker.getPosition()); + + } + }, 500); + + + } + }); return super.onCreateView(inflater, container, savedInstanceState); diff --git a/collect_app/src/main/res/layouts/fieldsight/drawable/ic_place_blue.xml b/collect_app/src/main/res/layouts/fieldsight/drawable/ic_place_blue.xml new file mode 100644 index 000000000..4438cdfe1 --- /dev/null +++ b/collect_app/src/main/res/layouts/fieldsight/drawable/ic_place_blue.xml @@ -0,0 +1,9 @@ + + + diff --git a/collect_app/src/main/res/layouts/fieldsight/layout/activity_site_map.xml b/collect_app/src/main/res/layouts/fieldsight/layout/activity_site_map.xml new file mode 100644 index 000000000..dbb028358 --- /dev/null +++ b/collect_app/src/main/res/layouts/fieldsight/layout/activity_site_map.xml @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/collect_app/src/main/res/layouts/fieldsight/layout/project_map_layout.xml b/collect_app/src/main/res/layouts/fieldsight/layout/project_map_layout.xml new file mode 100644 index 000000000..5b1aea7fd --- /dev/null +++ b/collect_app/src/main/res/layouts/fieldsight/layout/project_map_layout.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + +