Skip to content

Commit

Permalink
Apply Pull Request maplibre#510 (Set LocationEngine properties in and…
Browse files Browse the repository at this point in the history
  • Loading branch information
gibbsnich committed Jan 15, 2025
1 parent 8246a84 commit 93dde0d
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import android.content.Context;
import android.graphics.Point;
import android.util.DisplayMetrics;
import android.util.Log;
import org.maplibre.android.location.engine.LocationEngineRequest;
import org.maplibre.geojson.Polygon;
import org.maplibre.android.camera.CameraPosition;
import org.maplibre.android.camera.CameraUpdate;
Expand Down Expand Up @@ -133,6 +135,17 @@ static LatLngBounds toLatLngBounds(Object o) {
return builder.build();
}

static LocationEngineRequest toLocationEngineRequest(Object o) {
if (o == null) {
return null;
}
List<?> data = toList(o);
return new LocationEngineRequest.Builder(toInt(data.get(0)))
.setPriority(toInt(data.get(1)))
.setDisplacement(toInt(data.get(2)))
.build();
}

static List<LatLng> toLatLngList(Object o, boolean flippedOrder) {
if (o == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package org.maplibre.maplibregl;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import org.maplibre.android.location.engine.LocationEngineCallback;
import org.maplibre.android.location.engine.LocationEngineRequest;
import org.maplibre.android.location.engine.LocationEngineResult;
import org.maplibre.android.location.engine.LocationEngineImpl;


public class MapLibreGPSLocationEngine implements LocationEngineImpl<LocationListener> {
private static final String TAG = "GPSLocationEngine";
final LocationManager locationManager;

String currentProvider = LocationManager.PASSIVE_PROVIDER;

public MapLibreGPSLocationEngine(@NonNull Context context) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}

@NonNull
@Override
public LocationListener createListener(LocationEngineCallback<LocationEngineResult> callback) {
return new AndroidLocationEngineCallbackTransport(callback);
}

@Override
public void getLastLocation(@NonNull LocationEngineCallback<LocationEngineResult> callback)
throws SecurityException {
Location lastLocation = getLastLocationFor(currentProvider);
if (lastLocation != null) {
callback.onSuccess(LocationEngineResult.create(lastLocation));
return;
}

for (String provider : locationManager.getAllProviders()) {
lastLocation = getLastLocationFor(provider);
if (lastLocation != null) {
callback.onSuccess(LocationEngineResult.create(lastLocation));
return;
}
}
callback.onFailure(new Exception("Last location unavailable"));
}

@SuppressLint("MissingPermission")
Location getLastLocationFor(String provider) throws SecurityException {
Location location = null;
try {
location = locationManager.getLastKnownLocation(provider);
} catch (IllegalArgumentException iae) {
Log.e(TAG, iae.toString());
}
return location;
}

@SuppressLint("MissingPermission")
@Override
public void requestLocationUpdates(@NonNull LocationEngineRequest request,
@NonNull LocationListener listener,
@Nullable Looper looper) throws SecurityException {
currentProvider = getBestProvider(request.getPriority());
locationManager.requestLocationUpdates(currentProvider, request.getInterval(), request.getDisplacement(),
listener, looper);
}

@SuppressLint("MissingPermission")
@Override
public void requestLocationUpdates(@NonNull LocationEngineRequest request,
@NonNull PendingIntent pendingIntent) throws SecurityException {
currentProvider = getBestProvider(request.getPriority());
locationManager.requestLocationUpdates(currentProvider, request.getInterval(),
request.getDisplacement(), pendingIntent);
}

@SuppressLint("MissingPermission")
@Override
public void removeLocationUpdates(@NonNull LocationListener listener) {
if (listener != null) {
locationManager.removeUpdates(listener);
}
}

@Override
public void removeLocationUpdates(PendingIntent pendingIntent) {
if (pendingIntent != null) {
locationManager.removeUpdates(pendingIntent);
}
}

private String getBestProvider(int priority) {
String provider = null;
if (priority != LocationEngineRequest.PRIORITY_NO_POWER) {
provider = LocationManager.GPS_PROVIDER;
}
return provider != null ? provider : LocationManager.PASSIVE_PROVIDER;
}


@VisibleForTesting
static final class AndroidLocationEngineCallbackTransport implements LocationListener {
private final LocationEngineCallback<LocationEngineResult> callback;

AndroidLocationEngineCallbackTransport(LocationEngineCallback<LocationEngineResult> callback) {
this.callback = callback;
}

@Override
public void onLocationChanged(Location location) {
callback.onSuccess(LocationEngineResult.create(location));
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
// noop
}

@Override
public void onProviderEnabled(String s) {
// noop
}

@Override
public void onProviderDisabled(String s) {
callback.onFailure(new Exception("Current provider disabled"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import androidx.annotation.NonNull;
import org.maplibre.android.camera.CameraPosition;
import org.maplibre.android.geometry.LatLngBounds;
import org.maplibre.android.location.engine.LocationEngineRequest;
import org.maplibre.android.maps.MapLibreMapOptions;
import io.flutter.plugin.common.BinaryMessenger;

Expand All @@ -23,6 +24,7 @@ class MapLibreMapBuilder implements MapLibreMapOptionsSink {
private int myLocationRenderMode = 0;
private String styleString = "";
private LatLngBounds bounds = null;
private LocationEngineRequest locationEngineRequest = null;

MapLibreMapController build(
int id,
Expand All @@ -43,6 +45,10 @@ MapLibreMapController build(
controller.setCameraTargetBounds(bounds);
}

if (null != locationEngineRequest) {
controller.setLocationEngineProperties(locationEngineRequest);
}

return controller;
}

Expand Down Expand Up @@ -206,4 +212,9 @@ public void setAttributionButtonMargins(int x, int y) {
public void setDragEnabled(boolean enabled) {
this.dragEnabled = enabled;
}

@Override
public void setLocationEngineProperties(@NonNull LocationEngineRequest locationEngineRequest) {
this.locationEngineRequest = locationEngineRequest;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
import com.google.gson.JsonParser;
import org.maplibre.android.gestures.AndroidGesturesManager;
import org.maplibre.android.gestures.MoveGestureDetector;
import org.maplibre.android.location.engine.LocationEngine;
import org.maplibre.android.location.engine.LocationEngineDefault;
import org.maplibre.android.location.engine.LocationEngineProxy;
import org.maplibre.android.location.engine.LocationEngineRequest;
import org.maplibre.geojson.Feature;
import org.maplibre.geojson.FeatureCollection;
import org.maplibre.android.camera.CameraPosition;
Expand Down Expand Up @@ -1868,6 +1872,20 @@ public void setCompassEnabled(boolean compassEnabled) {
mapLibreMap.getUiSettings().setCompassEnabled(compassEnabled);
}

@Override
public void setLocationEngineProperties(LocationEngineRequest locationEngineRequest){
if(locationComponent != null){
if(locationEngineRequest.getPriority() == LocationEngineRequest.PRIORITY_HIGH_ACCURACY){
locationComponent.setLocationEngine(new LocationEngineProxy(
new MapLibreGPSLocationEngine(context)));
} else {
locationComponent.setLocationEngine(
LocationEngineDefault.INSTANCE.getDefaultLocationEngine(context));
}
locationComponent.setLocationEngineRequest(locationEngineRequest);
}
}

@Override
public void setTrackCameraPosition(boolean trackCameraPosition) {
this.trackCameraPosition = trackCameraPosition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package org.maplibre.maplibregl

import org.maplibre.android.geometry.LatLngBounds
import org.maplibre.android.location.engine.LocationEngineRequest

/** Receiver of MapLibreMap configuration options. */
internal interface MapLibreMapOptionsSink {
Expand Down Expand Up @@ -42,4 +43,6 @@ internal interface MapLibreMapOptionsSink {
fun setAttributionButtonGravity(gravity: Int)

fun setAttributionButtonMargins(x: Int, y: Int)

fun setLocationEngineProperties(locationEngineRequest: LocationEngineRequest)
}
3 changes: 3 additions & 0 deletions maplibre_gl/lib/maplibre_gl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export 'package:maplibre_gl_platform_interface/maplibre_gl_platform_interface.da
LatLngQuad,
Line,
LineOptions,
LocationEngineAndroidProperties,
LocationEnginePlatforms,
LocationPriority,
MapLibreMethodChannel,
MapLibrePlatform,
MinMaxZoomPreference,
Expand Down
10 changes: 10 additions & 0 deletions maplibre_gl/lib/src/maplibre_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MapLibreMap extends StatefulWidget {
this.styleString = MapLibreStyles.demo,
this.onMapCreated,
this.onStyleLoadedCallback,
this.locationEnginePlatforms = LocationEnginePlatforms.defaultPlatform,
this.gestureRecognizers,
this.compassEnabled = true,
this.cameraTargetBounds = CameraTargetBounds.unbounded,
Expand Down Expand Up @@ -67,6 +68,10 @@ class MapLibreMap extends StatefulWidget {
assert(annotationOrder.length <= 4),
assert(annotationConsumeTapEvents.length > 0);

/// The properties for the platform-specific location engine.
/// Only has an impact if [myLocationEnabled] is set to true.
final LocationEnginePlatforms locationEnginePlatforms;

/// Defines the layer order of annotations displayed on map
///
/// Any annotation type can only be contained once, so 0 to 4 types
Expand Down Expand Up @@ -357,10 +362,12 @@ class _MapLibreMapOptions {
this.compassViewMargins,
this.attributionButtonPosition,
this.attributionButtonMargins,
this.locationEnginePlatforms
});

_MapLibreMapOptions.fromWidget(MapLibreMap map)
: this(
locationEnginePlatforms: map.locationEnginePlatforms,
compassEnabled: map.compassEnabled,
cameraTargetBounds: map.cameraTargetBounds,
styleString: map.styleString,
Expand Down Expand Up @@ -418,6 +425,8 @@ class _MapLibreMapOptions {

final Point? attributionButtonMargins;

final LocationEnginePlatforms? locationEnginePlatforms;

final _gestureGroup = {
'rotateGesturesEnabled',
'scrollGesturesEnabled',
Expand Down Expand Up @@ -464,6 +473,7 @@ class _MapLibreMapOptions {
addIfNonNull('attributionButtonPosition', attributionButtonPosition?.index);
addIfNonNull(
'attributionButtonMargins', pointToArray(attributionButtonMargins));
addIfNonNull('locationEngineProperties', locationEnginePlatforms?.toList());
return optionsMap;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
library maplibre_gl_platform_interface;

import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'dart:math';
import 'package:flutter/foundation.dart';
Expand All @@ -20,3 +21,4 @@ part 'src/fill.dart';
part 'src/ui.dart';
part 'src/maplibre_gl_platform_interface.dart';
part 'src/source_properties.dart';
part 'src/location_engine_properties.dart';
Loading

0 comments on commit 93dde0d

Please sign in to comment.