Add a marker and circle of accuracy for current location

Currently the user's position is not visible on the map. This
commit adds a marker to the user's position and a circular
polygon which shows the accuracy of the location measurement.
This commit is contained in:
Tobias Schönberg 2017-05-28 17:50:53 +02:00
parent 4b400cd8aa
commit 4f4a875ebe
6 changed files with 73 additions and 7 deletions

View file

@ -262,7 +262,7 @@ public class MediaDataExtractor {
NodeList childNodes = parentNode.getChildNodes();
double latitudeText = Double.parseDouble(childNodes.item(1).getTextContent());
double longitudeText = Double.parseDouble(childNodes.item(2).getTextContent());
LatLng coordinates = new LatLng(latitudeText, longitudeText);
LatLng coordinates = new LatLng(latitudeText, longitudeText, 0);
return coordinates.getPrettyCoordinateString();
}

View file

@ -4,6 +4,7 @@ public class LatLng {
public final double latitude;
public final double longitude;
public final float accuracy;
/** Accepts latitude and longitude.
* North and South values are cut off at 90°
@ -11,13 +12,14 @@ public class LatLng {
* @param latitude double value
* @param longitude double value
*/
public LatLng(double latitude, double longitude) {
public LatLng(double latitude, double longitude, float accuracy) {
if(-180.0D <= longitude && longitude < 180.0D) {
this.longitude = longitude;
} else {
this.longitude = ((longitude - 180.0D) % 360.0D + 360.0D) % 360.0D - 180.0D;
}
this.latitude = Math.max(-90.0D, Math.min(90.0D, latitude));
this.accuracy = accuracy;
}
public int hashCode() {

View file

@ -14,6 +14,7 @@ public class LocationServiceManager implements LocationListener {
private String provider;
private LocationManager locationManager;
private LatLng latestLocation;
private Float latestLocationAccuracy;
public LocationServiceManager(Context context) {
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
@ -24,6 +25,16 @@ public class LocationServiceManager implements LocationListener {
return latestLocation;
}
/**
* Returns the accuracy of the location. The measurement is
* given as a radius in meter of 68 % confidence.
*
* @return Float
*/
public Float getLatestLocationAccuracy() {
return latestLocationAccuracy;
}
/** Registers a LocationManager to listen for current location.
*/
public void registerLocationManager() {
@ -57,9 +68,10 @@ public class LocationServiceManager implements LocationListener {
public void onLocationChanged(Location location) {
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
Timber.d("Latitude: %f Longitude: %f", currentLatitude, currentLongitude);
latestLocationAccuracy = location.getAccuracy();
Timber.d("Latitude: %f Longitude: %f Accuracy %f", currentLatitude, currentLongitude, latestLocationAccuracy);
latestLocation = new LatLng(currentLatitude, currentLongitude);
latestLocation = new LatLng(currentLatitude, currentLongitude, latestLocationAccuracy);
}
@Override

View file

@ -57,7 +57,7 @@ public class NearbyInfoDialog extends OverlayDialog {
Bundle bundle = getArguments();
placeTitle.setText(bundle.getString(ARG_TITLE));
placeDescription.setText(bundle.getString(ARG_DESC));
location = new LatLng(bundle.getDouble(ARG_LATITUDE), bundle.getDouble(ARG_LONGITUDE));
location = new LatLng(bundle.getDouble(ARG_LATITUDE), bundle.getDouble(ARG_LONGITUDE), 0);
getArticleLink(bundle);
}

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.nearby;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -14,6 +15,8 @@ import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
@ -24,6 +27,7 @@ import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.services.android.telemetry.MapboxTelemetry;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import fr.free.nrw.commons.R;
@ -102,6 +106,8 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
return false;
}
});
addCurrentLocationMarker(mapboxMap);
}
});
if (PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("theme",true)) {
@ -111,6 +117,52 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
}
}
/**
* Adds a marker for the user's current position. Adds a
* circle which uses the accuracy * 2, to draw a circle
* which represents the user's position with an accuracy
* of 95%.
*/
public void addCurrentLocationMarker(MapboxMap mapboxMap) {
MarkerOptions currentLocationMarker = new MarkerOptions()
.position(new LatLng(curLatLng.latitude, curLatLng.longitude));
mapboxMap.addMarker(currentLocationMarker);
List<LatLng> circle = createCircleArray(curLatLng.latitude, curLatLng.longitude,
curLatLng.accuracy * 2, 100);
mapboxMap.addPolygon(
new PolygonOptions()
.addAll(circle)
.strokeColor(Color.parseColor("#55000000"))
.fillColor(Color.parseColor("#11000000"))
);
}
/**
* Creates a series of points that create a circle on the map.
* Takes the center latitude, center longitude of the circle,
* the radius in meter and the number of nodes of the circle.
*
* @return List List of LatLng points of the circle.
*/
public List<LatLng> createCircleArray(double centerLat, double centerLong, float radius, int nodes) {
List<LatLng> circle = new ArrayList<>();
float radiusKilometer = radius / 1000;
double radiusLong = radiusKilometer /
(111.320 * Math.cos(centerLat * Math.PI / 180));
double radiusLat = radiusKilometer / 110.574;
for (int i = 0; i < nodes; i++) {
double theta = ((double) i / (double) nodes) * (2 * Math.PI);
double nodeLongitude = centerLong + radiusLong * Math.cos(theta);
double nodeLatitude = centerLat + radiusLat * Math.sin(theta);
circle.add(new LatLng(nodeLatitude, nodeLongitude));
}
return circle;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

View file

@ -125,7 +125,7 @@ public class NearbyPlaces {
type, // list
type, // details
Uri.parse(icon),
new LatLng(latitude, longitude),
new LatLng(latitude, longitude, 0),
new Sitelinks.Builder()
.setWikipediaLink(wikipediaSitelink)
.setCommonsLink(commonsSitelink)
@ -187,7 +187,7 @@ public class NearbyPlaces {
type, // list
type, // details
null,
new LatLng(latitude, longitude),
new LatLng(latitude, longitude, 0),
new Sitelinks.Builder().build()
));
}