使用地理位置,mapbox可在Android上实时显示多个位置

时间:2017-06-04 09:35:36

标签: android mapbox geofire

我使用Geofire / Geoquery解雇的Mapbox来获取我当前的用户位置。我想在Mapbox地图上放置标记以实时显示我的用户。我用:

// object or in the same activity which contains the mapview.
Mapbox.getInstance(this, getString(R.string.access_token));

mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(final MapboxMap mapboxMap) {
        map = mapboxMap;

        GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), 100);

        geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
            @Override
            public void onKeyEntered(String key, GeoLocation location) {
                Log.d("test","Key "+key+" entered the search area at ["+location.latitude+","+location.longitude+"]");
                mapboxMap.addMarker(new MarkerOptions().position(new LatLng(location.latitude, location.longitude)));
            }

            @Override
            public void onKeyExited(String key) {
                Log.d("test","Key %s is no longer in the search area"+key);
            }

            @Override
            public void onKeyMoved(String key, GeoLocation location) {
                Log.d("test", "Key %s moved within the search area to [%f,%f]" + key + location.latitude + location.longitude);
            }

            @Override
            public void onGeoQueryReady() {
                Log.d("test","All initial data has been loaded and events have been fired!");
            }

            @Override
            public void onGeoQueryError(DatabaseError error) {
                Log.d("test","There was an error with this query: " + error);
            }
        });


    }
});

这是有效的,但这是我第一次开始活动时,现在我使用SFVehicles示例创建实时查询:

private GeoFire geoFire;
private GeoQuery geoQuery;
private MapView mapView;
private MapboxMap map;
private Map<String,Marker> markers;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rallye_main);

    // setup map and camera position
    SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);

    this.map = mapFragment.getMap();

    LatLng latLngCenter = new LatLng(INITIAL_CENTER.latitude, INITIAL_CENTER.longitude);
    this.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCenter, INITIAL_ZOOM_LEVEL));
    this.map.setOnCameraChangeListener(this);

    FirebaseOptions options = new FirebaseOptions.Builder().setApplicationId("geofire").build();
    FirebaseApp app = FirebaseApp.initializeApp(this, options);

    // setup GeoFire
    this.geoFire = new GeoFire(FirebaseDatabase.getInstance(app).getReferenceFromUrl(GEO_FIRE_REF));
    // radius in km gibt alle positionen der Teilnehmer im radius von x km aus
    this.geoQuery = this.geoFire.queryAtLocation(INITIAL_CENTER, 50);

    // setup markers
    this.markers = new HashMap<String, Marker>();

}

@Override
protected void onStop() {
    super.onStop();
    // remove all event listeners to stop updating in the background
    this.geoQuery.removeAllListeners();
    for (Marker marker: this.markers.values()) {
        marker.remove();
    }
    this.markers.clear();
}

@Override
protected void onStart() {
    super.onStart();
    // add an event listener to start updating locations again
    this.geoQuery.addGeoQueryEventListener(this);
}

@Override
public void onKeyEntered(String key, GeoLocation location) {
    // Add a new marker to the map
    Marker marker = this.map.addMarker(new MarkerOptions().position(new LatLng(location.latitude, location.longitude)));
    this.markers.put(key, marker);
}

@Override
public void onKeyExited(String key) {
    // Remove any old marker
    Marker marker = this.markers.get(key);
    if (marker != null) {
        marker.remove();
        this.markers.remove(key);
    }
}

@Override
public void onKeyMoved(String key, GeoLocation location) {
    // Move the marker
    Marker marker = this.markers.get(key);
    if (marker != null) {
        this.animateMarkerTo(marker, location.latitude, location.longitude);
    }
}

@Override
public void onGeoQueryReady() {
}

@Override
public void onGeoQueryError(DatabaseError error) {
    new AlertDialog.Builder(this)
            .setTitle("Error")
            .setMessage("There was an unexpected error querying GeoFire: " + error.getMessage())
            .setPositiveButton(android.R.string.ok, null)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .show();
}

// Animation handler for old APIs without animation support
private void animateMarkerTo(final Marker marker, final double lat, final double lng) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final long DURATION_MS = 3000;
    final Interpolator interpolator = new AccelerateDecelerateInterpolator();
    final LatLng startPosition = marker.getPosition();
    handler.post(new Runnable() {
        @Override
        public void run() {
            float elapsed = SystemClock.uptimeMillis() - start;
            float t = elapsed/DURATION_MS;
            float v = interpolator.getInterpolation(t);

            //double currentLat = (lat - startPosition.latitude) * v + startPosition.latitude;
            //double currentLng = (lng - startPosition.longitude) * v + startPosition.longitude;
            double currentLat = (lat - startPosition.getLatitude()) * v + startPosition.getLatitude();
            double currentLng = (lng - startPosition.getLongitude()) * v + startPosition.getLongitude();
            marker.setPosition(new LatLng(currentLat, currentLng));

            // if animation is not finished yet, repeat
            if (t < 1) {
                handler.postDelayed(this, 16);
            }
        }
    });
}

private double zoomLevelToRadius(double zoomLevel) {
    // Approximation to fit circle into view
    return 16384000/Math.pow(2, zoomLevel);
}


@Override
public void onCameraChange(CameraPosition cameraPosition) {
    // Update the search criteria for this geoQuery and the circle on the map
    LatLng center = cameraPosition.target;
    double radius = zoomLevelToRadius(cameraPosition.zoom);
    this.geoQuery.setCenter(new GeoLocation(center.getLatitude(), center.getLongitude()));
    // radius in km
    this.geoQuery.setRadius(radius/1000);
}

使用Google地图的示例代码,但我必须使用Mapbox提供离线地图,我在此行中收到错误:

SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);

this.map = mapFragment.getMap();

具体做法是:

Cannot resolve Method getMap()

我已尝试过类似的内容:

mapFragment.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(MapboxMap mapboxMap) {

        // Customize map with markers, polylines, etc.

    }
});

但没有,我收到这个错误:

FATAL EXCEPTION: main Process: com.test.bla, PID: 30149
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.bla/com.test.bla.rallye.rallye_main}: android.view.InflateException: Binary XML file line >#2: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2689)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5938)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
at android.view.LayoutInflater.inflate(LayoutInflater.java:483)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
at android.transition.Scene.enter(Scene.java:175)
at com.android.internal.policy.impl.PhoneWindow.transitionTo(PhoneWindow.java:483)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:426)
at android.app.Activity.setContentView(Activity.java:2267).....

我无法将此示例从Google mapx转换为Mapbox

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:mapbox_cameraTargetLat="52.00000"
        mapbox:mapbox_cameraTargetLng="8.00000"
        mapbox:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
        mapbox:mapbox_cameraZoom="12"/>

</RelativeLayout>

或我的第二次尝试:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

1 个答案:

答案 0 :(得分:0)

看起来布局xml中的某些内容不正确。您是要试图给谷歌地图或地图集地图充气吗?请包含布局XML。