Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions androidshared/src/main/res/color/color_primary_low_emphasis.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package org.odk.collect.android.support
import android.os.Handler
import android.os.Looper
import androidx.fragment.app.Fragment
import org.odk.collect.maps.traces.LineDescription
import org.odk.collect.maps.MapFragment
import org.odk.collect.maps.MapPoint
import org.odk.collect.maps.circles.CircleDescription
import org.odk.collect.maps.traces.PolygonDescription
import org.odk.collect.maps.markers.MarkerDescription
import org.odk.collect.maps.markers.MarkerIconDescription
import org.odk.collect.maps.traces.LineDescription
import org.odk.collect.maps.traces.PolygonDescription

class FakeClickableMapFragment : Fragment(), MapFragment {

Expand Down Expand Up @@ -97,6 +97,7 @@ class FakeClickableMapFragment : Fragment(), MapFragment {
}

override fun clearFeatures() {}
override fun clearFeatures(ids: List<Int>) {}

override fun setClickListener(listener: MapFragment.PointListener?) {}

Expand All @@ -108,16 +109,6 @@ class FakeClickableMapFragment : Fragment(), MapFragment {

override fun setDragEndListener(listener: MapFragment.FeatureListener?) {}

override fun setGpsLocationEnabled(enabled: Boolean) {}

override fun getGpsLocation(): MapPoint? {
return null
}

override fun setGpsLocationListener(listener: MapFragment.PointListener?) {}

override fun setRetainMockAccuracy(retainMockAccuracy: Boolean) {}

override fun hasCenter(): Boolean {
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ class CollectGoogleMapsDependencyModule(
return appDependencyComponent.referenceLayerRepository()
}

override fun providesLocationClient(): LocationClient {
return appDependencyComponent.locationClient()
}

override fun providesSettingsProvider(): SettingsProvider {
return appDependencyComponent.settingsProvider()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.odk.collect.android.injection.config

import org.odk.collect.android.geo.MapConfiguratorProvider
import org.odk.collect.location.LocationClient
import org.odk.collect.maps.MapConfigurator
import org.odk.collect.maps.layers.ReferenceLayerRepository
import org.odk.collect.osmdroid.OsmDroidDependencyModule
Expand All @@ -15,10 +14,6 @@ class CollectOsmDroidDependencyModule(
return appDependencyComponent.referenceLayerRepository()
}

override fun providesLocationClient(): LocationClient {
return appDependencyComponent.locationClient()
}

override fun providesMapConfigurator(): MapConfigurator {
return MapConfiguratorProvider.getConfigurator(
appDependencyComponent.settingsProvider().getUnprotectedSettings().getString(ProjectKeys.KEY_BASEMAP_SOURCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class NoOpMapFragment : Fragment(), MapFragment {
override fun clearFeatures() {
}

override fun clearFeatures(ids: List<Int>) {
}

override fun setClickListener(listener: MapFragment.PointListener?) {
}

Expand All @@ -118,19 +121,6 @@ class NoOpMapFragment : Fragment(), MapFragment {
override fun setDragEndListener(listener: MapFragment.FeatureListener?) {
}

override fun setGpsLocationEnabled(enabled: Boolean) {
}

override fun getGpsLocation(): MapPoint? {
TODO("Not yet implemented")
}

override fun setGpsLocationListener(listener: MapFragment.PointListener?) {
}

override fun setRetainMockAccuracy(retainMockAccuracy: Boolean) {
}

override fun hasCenter(): Boolean {
return false
}
Expand Down
26 changes: 26 additions & 0 deletions geo/src/main/java/org/odk/collect/geo/GeoUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ package org.odk.collect.geo

import android.content.Context
import android.location.Location
import androidx.fragment.app.Fragment
import androidx.lifecycle.asLiveData
import org.javarosa.core.model.data.GeoPointData
import org.odk.collect.location.tracker.LocationTracker
import org.odk.collect.location.tracker.bindToLifecycle
import org.odk.collect.maps.MapFragment
import org.odk.collect.maps.MapPoint
import org.odk.collect.maps.circles.CurrentLocationDelegate
import org.odk.collect.shared.strings.StringUtils.removeEnd
import org.odk.collect.strings.R
import java.text.DecimalFormat
Expand Down Expand Up @@ -93,7 +99,27 @@ object GeoUtils {
return MapPoint(this.getPart(0), this.getPart(1), this.getPart(2), this.getPart(3))
}

@JvmStatic
fun org.odk.collect.location.Location.toMapPoint(): MapPoint {
return MapPoint(this.latitude, this.longitude, this.altitude, this.accuracy.toDouble())
}

@JvmStatic
@JvmOverloads
fun MapFragment.showCurrentLocation(
locationTracker: LocationTracker,
currentLocationDelegate: CurrentLocationDelegate,
retainMockAccuracy: Boolean = false,
afterUpdate: (MapPoint) -> Unit = {}
) {
val lifecycleOwner = this as Fragment
locationTracker.bindToLifecycle(lifecycleOwner, retainMockAccuracy)
locationTracker.getLocation().asLiveData().observe(lifecycleOwner) {
if (it != null) {
val mapPoint = it.toMapPoint()
currentLocationDelegate.update(this, mapPoint)
afterUpdate(mapPoint)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import static org.odk.collect.geo.Constants.EXTRA_READ_ONLY;
import static org.odk.collect.geo.Constants.EXTRA_RETAIN_MOCK_ACCURACY;
import static org.odk.collect.geo.GeoActivityUtils.requireLocationPermissions;
import static org.odk.collect.geo.GeoUtils.showCurrentLocation;
import static org.odk.collect.geo.GeoUtils.toMapPoint;
import static org.odk.collect.location.tracker.LocationTrackerKt.getCurrentLocation;

import android.annotation.SuppressLint;
import android.content.Intent;
Expand All @@ -38,9 +41,12 @@
import org.odk.collect.externalapp.ExternalAppUtils;
import org.odk.collect.geo.GeoDependencyComponentProvider;
import org.odk.collect.geo.R;
import org.odk.collect.location.Location;
import org.odk.collect.location.tracker.LocationTracker;
import org.odk.collect.maps.MapFragment;
import org.odk.collect.maps.MapFragmentFactory;
import org.odk.collect.maps.MapPoint;
import org.odk.collect.maps.circles.CurrentLocationDelegate;
import org.odk.collect.maps.layers.OfflineMapLayersPickerBottomSheetDialogFragment;
import org.odk.collect.maps.layers.ReferenceLayerRepository;
import org.odk.collect.maps.markers.MarkerDescription;
Expand All @@ -49,8 +55,11 @@
import org.odk.collect.strings.localization.LocalizedActivity;
import org.odk.collect.webpage.WebPageService;

import java.util.Arrays;

import javax.inject.Inject;

import kotlin.Unit;
import timber.log.Timber;

/**
Expand Down Expand Up @@ -96,6 +105,9 @@ public class GeoPointMapActivity extends LocalizedActivity {
@Inject
WebPageService webPageService;

@Inject
LocationTracker locationTracker;

private MapFragment map;
private int featureId = -1; // will be a positive featureId once map is ready

Expand All @@ -110,26 +122,35 @@ public class GeoPointMapActivity extends LocalizedActivity {
private ImageButton clearButton;

private boolean captureLocation;
private boolean foundFirstLocation;

/**
* True if a tap on the clear button removed an existing marker and
* no new marker has been placed.
*/
private boolean setClear;

/** True if the current point came from the intent. */
/**
* True if the current point came from the intent.
*/
private boolean pointFromIntent;

/** True if the intent requested for the point to be read-only. */
/**
* True if the intent requested for the point to be read-only.
*/
private boolean intentReadOnly;

/** True if the intent requested for the marker to be draggable. */
/**
* True if the intent requested for the marker to be draggable.
*/
private boolean intentDraggable;

/** While true, the point cannot be moved by dragging or long-pressing. */
/**
* While true, the point cannot be moved by dragging or long-pressing.
*/
private boolean isPointLocked;

private final CurrentLocationDelegate currentLocationDelegate = new CurrentLocationDelegate();

@Override
public void onCreate(Bundle savedInstanceState) {
((GeoDependencyComponentProvider) getApplication()).getGeoDependencyComponent().inject(this);
Expand Down Expand Up @@ -162,7 +183,8 @@ public void onCreate(Bundle savedInstanceState) {
mapFragment.init(this::initMap, this::finish);
}

@Override protected void onSaveInstanceState(Bundle state) {
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
if (map == null) {
// initMap() is called asynchronously, so map can be null if the activity
Expand All @@ -179,7 +201,6 @@ public void onCreate(Bundle savedInstanceState) {
// Flags
state.putBoolean(IS_DRAGGED_KEY, isDragged);
state.putBoolean(CAPTURE_LOCATION_KEY, captureLocation);
state.putBoolean(FOUND_FIRST_LOCATION_KEY, foundFirstLocation);
state.putBoolean(SET_CLEAR_KEY, setClear);
state.putBoolean(POINT_FROM_INTENT_KEY, pointFromIntent);
state.putBoolean(INTENT_READ_ONLY_KEY, intentReadOnly);
Expand Down Expand Up @@ -222,16 +243,18 @@ public void initMap(MapFragment newMapFragment) {

placeMarkerButton.setEnabled(false);
placeMarkerButton.setOnClickListener(v -> {
MapPoint mapPoint = map.getGpsLocation();
if (mapPoint != null) {
Location currentLocation = getCurrentLocation(locationTracker);

if (currentLocation != null) {
MapPoint mapPoint = toMapPoint(currentLocation);
placeMarker(mapPoint);
zoomToMarker(true);
}
});

// Focuses on marked location
zoomButton.setEnabled(false);
zoomButton.setOnClickListener(v -> map.zoomToCurrentLocation(map.getGpsLocation()));
zoomButton.setOnClickListener(v -> currentLocationDelegate.zoomToCurrentLocation(map));

// Menu Layer Toggle
findViewById(R.id.layer_menu).setOnClickListener(v -> {
Expand All @@ -242,11 +265,6 @@ public void initMap(MapFragment newMapFragment) {
clearButton.setEnabled(false);
clearButton.setOnClickListener(v -> {
clear();
if (map.getGpsLocation() != null) {
placeMarkerButton.setEnabled(true);
// locationStatus.setVisibility(View.VISIBLE);
}
// placeMarkerButton.setEnabled(true);
locationStatus.setVisibility(View.VISIBLE);
pointFromIntent = false;
});
Expand Down Expand Up @@ -279,24 +297,24 @@ public void initMap(MapFragment newMapFragment) {
pointFromIntent = true;
locationStatus.setVisibility(View.GONE);
zoomButton.setEnabled(true);
foundFirstLocation = true;
zoomToMarker(false);
}
}

map.setRetainMockAccuracy(intent.getBooleanExtra(EXTRA_RETAIN_MOCK_ACCURACY, false));
map.setGpsLocationListener(this::onLocationChanged);
map.setGpsLocationEnabled(true);

if (previousState != null) {
restoreFromInstanceState(previousState);
}

boolean retainMockAccuracy = getIntent().getBooleanExtra(EXTRA_RETAIN_MOCK_ACCURACY, false);
showCurrentLocation(map, locationTracker, currentLocationDelegate, retainMockAccuracy, mapPoint -> {
onLocationChanged(mapPoint);
return Unit.INSTANCE;
});
}

protected void restoreFromInstanceState(Bundle state) {
isDragged = state.getBoolean(IS_DRAGGED_KEY, false);
captureLocation = state.getBoolean(CAPTURE_LOCATION_KEY, false);
foundFirstLocation = state.getBoolean(FOUND_FIRST_LOCATION_KEY, false);
setClear = state.getBoolean(SET_CLEAR_KEY, false);
pointFromIntent = state.getBoolean(POINT_FROM_INTENT_KEY, false);
intentReadOnly = state.getBoolean(INTENT_READ_ONLY_KEY, false);
Expand All @@ -314,7 +332,6 @@ protected void restoreFromInstanceState(Bundle state) {
// Restore the flags again, because placeMarker() and clear() modify some of them.
isDragged = state.getBoolean(IS_DRAGGED_KEY, false);
captureLocation = state.getBoolean(CAPTURE_LOCATION_KEY, false);
foundFirstLocation = state.getBoolean(FOUND_FIRST_LOCATION_KEY, false);
setClear = state.getBoolean(SET_CLEAR_KEY, false);
pointFromIntent = state.getBoolean(POINT_FROM_INTENT_KEY, false);
intentReadOnly = state.getBoolean(INTENT_READ_ONLY_KEY, false);
Expand All @@ -333,8 +350,6 @@ public void onLocationChanged(MapPoint point) {
placeMarkerButton.setEnabled(true);
}

this.location = point;

if (point != null) {
enableZoomButton(true);

Expand All @@ -343,11 +358,6 @@ public void onLocationChanged(MapPoint point) {
placeMarkerButton.setEnabled(true);
}

if (!foundFirstLocation) {
map.zoomToCurrentLocation(map.getGpsLocation());
foundFirstLocation = true;
}

locationStatus.setAccuracy(new LocationAccuracy.Improving((float) point.accuracy));
}
}
Expand Down Expand Up @@ -384,7 +394,7 @@ public void zoomToMarker(boolean animate) {
}

private void clear() {
map.clearFeatures();
map.clearFeatures(Arrays.asList(featureId));
featureId = -1;
clearButton.setEnabled(false);

Expand All @@ -394,9 +404,16 @@ private void clear() {
setClear = true;
}

/** Places the marker and enables the button to remove it. */
/**
* Places the marker and enables the button to remove it.
*/
private void placeMarker(@NonNull MapPoint point) {
map.clearFeatures();
this.location = point;

if (featureId != -1) {
map.clearFeatures(Arrays.asList(featureId));
}

featureId = map.addMarker(new MarkerDescription(point, intentDraggable && !intentReadOnly && !isPointLocked, MapFragment.IconAnchor.CENTER, new MarkerIconDescription.DrawableResource(org.odk.collect.icons.R.drawable.ic_map_point)));
if (!intentReadOnly) {
clearButton.setEnabled(true);
Expand Down
Loading