geofire android 存储和检索位置并将其显示在地图上

Posted

技术标签:

【中文标题】geofire android 存储和检索位置并将其显示在地图上【英文标题】:geofire android to store and retrive locations and display it on map 【发布时间】:2017-04-18 23:00:04 【问题描述】:

我正在用 android 开发一个出租车应用程序。我需要存储我的出租车的检索和更新位置,并使用 geofire 在地图上显示它。我已使用 firebase 进行身份验证。

需要一个完整的 android geofire 教程,但找不到任何

我也看过 SFVehicle 的例子,但不太了解

任何帮助将不胜感激!!!

【问题讨论】:

【参考方案1】:

首先,目前还没有关于 geofire 的完整教程,因此您可以使用的只有 Geofire go for java 和 js 的官方文档。这里有一个小但可能有用的东西—— https://firebase.googleblog.com/2013/09/geofire-location-queries-for-fun-and.html, https://medium.com/google-cloud/firebase-is-cool-geofire-is-just-awesome-b7f2be5e0f0f#.x78gjws28, 我希望这些可以对你有所帮助。

【讨论】:

【参考方案2】:

我为 Android 创建了一个库,它提供基于地理位置的 Firestore 数据,以在 KM / MILES 中查找给定半径内的数据列表。

它还可以在单​​个查询读取中提供更快的响应,并通过实时更新对查询中的 ADDED 和 REMOVED 数据进行分类。

您可以参考Geo-Firestore

它有完善的文档,因此您可以轻松地开发它。

【讨论】:

【参考方案3】:

这里还有一些链接 https://firebase.googleblog.com/2014/08/geofire-goes-mobile.html https://firebase.googleblog.com/2014/06/geofire-20.html How to save GeoFire coordinates along with other items in Firebase database?

【讨论】:

【参考方案4】:

这是一个获取驱动程序当前位置的示例代码

public class MainActivity extends AppCompatActivity implements
    OnMapReadyCallback, PermissionsListener 
// Variables needed to initialize a map
private MapboxMap mapboxMap;
private MapView mapView;
// Variables needed to handle location permissions
private PermissionsManager permissionsManager;
// Variables needed to add the location engine
private LocationEngine locationEngine;
private long DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L;
private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS *1;
// Variables needed to listen to location updates
private MainActivityLocationCallback callback = new MainActivityLocationCallback(this);

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, "");

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_main);

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(this);


@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) 
    this.mapboxMap = mapboxMap;

    mapboxMap.setStyle(Style.TRAFFIC_NIGHT,
            new Style.OnStyleLoaded() 
                @Override
                public void onStyleLoaded(@NonNull Style style) 
                    enableLocationComponent(style);
                
            );


/**
 * Initialize the Maps SDK's LocationComponent
 */
@SuppressWarnings( "MissingPermission")
private void enableLocationComponent(@NonNull Style loadedMapStyle) 
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) 

        // Get an instance of the component
        LocationComponent locationComponent = mapboxMap.getLocationComponent();

        // Set the LocationComponent activation options
        LocationComponentActivationOptions locationComponentActivationOptions =
                LocationComponentActivationOptions.builder(this, loadedMapStyle)
                        .useDefaultLocationEngine(false)
                        .build();

        // Activate with the LocationComponentActivationOptions object
        locationComponent.activateLocationComponent(locationComponentActivationOptions);

        // Enable to make component visible
        locationComponent.setLocationComponentEnabled(true);

        // Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        // Set the component's render mode
        locationComponent.setRenderMode(RenderMode.COMPASS);

        initLocationEngine();
     else 
        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    


/**
 * Set up the LocationEngine and the parameters for querying the device's location
 */
@SuppressLint("MissingPermission")
private void initLocationEngine() 
    locationEngine = LocationEngineProvider.getBestLocationEngine(this);

    LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
            .setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build();

    locationEngine.requestLocationUpdates(request, callback, getMainLooper());
    locationEngine.getLastLocation(callback);


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);


@Override
public void onExplanationNeeded(List<String> permissionsToExplain) 
    Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();


@Override
public void onPermissionResult(boolean granted) 
    if (granted) 
        if (mapboxMap.getStyle() != null) 
            enableLocationComponent(mapboxMap.getStyle());
        
     else 
        Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
        finish();
    


private static class MainActivityLocationCallback
        implements LocationEngineCallback<LocationEngineResult> 

    private final WeakReference<MainActivity> activityWeakReference;

    MainActivityLocationCallback(MainActivity activity) 
        this.activityWeakReference = new WeakReference<>(activity);
    

    /**
     * The LocationEngineCallback interface's method which fires when the device's location has changed.
     *
     * @param result the LocationEngineResult object which has the last known location within it.
     */
    @Override
    public void onSuccess(LocationEngineResult result) 
        MainActivity activity = activityWeakReference.get();

        if (activity != null) 
            Location location = result.getLastLocation();

            if (location == null) 
                return;
            
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            String somi_id2 = "emp_samad";
            DatabaseReference myRef3 = database.getReference("current");
            GeoFire geoFire = new GeoFire(myRef3);
            geoFire.setLocation(somi_id2,new GeoLocation(location.getLatitude(),location.getLongitude()));

            Toast.makeText(activity,String.valueOf(location.getLatitude()+"\n"+String.valueOf(location.getLongitude())),Toast.LENGTH_SHORT).show();

            // Pass the new location to the Maps SDK's LocationComponent
            if (activity.mapboxMap != null && result.getLastLocation() != null) 
                activity.mapboxMap.getLocationComponent().forceLocationUpdate(result.getLastLocation());
            
        
    

    /**
     * The LocationEngineCallback interface's method which fires when the device's location can not be captured
     *
     * @param exception the exception message
     */
    @Override
    public void onFailure(@NonNull Exception exception) 
        Log.d("LocationChangeActivity", exception.getLocalizedMessage());
        MainActivity activity = activityWeakReference.get();
        if (activity != null) 
            Toast.makeText(activity, exception.getLocalizedMessage(),
                    Toast.LENGTH_SHORT).show();
        
    


@Override
protected void onStart() 
    super.onStart();
    mapView.onStart();


@Override
protected void onResume() 
    super.onResume();
    mapView.onResume();


@Override
protected void onPause() 
    super.onPause();
    mapView.onPause();


@Override
protected void onStop() 
    super.onStop();
    mapView.onStop();


@Override
protected void onSaveInstanceState(Bundle outState) 
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);


@Override
protected void onDestroy() 
    super.onDestroy();
    // Prevent leaks
    if (locationEngine != null) 
        locationEngine.removeLocationUpdates(callback);
    
    mapView.onDestroy();


@Override
public void onLowMemory() 
    super.onLowMemory();
    mapView.onLowMemory();


现在是在地图上实时显示他的代码

    public class MainActivity extends AppCompatActivity  
      implements
        OnMapReadyCallback, PermissionsListener

    private MapView mapView;
    private PermissionsManager permissionsManager;
    private MapboxMap mapboxMap;
    private GeoJsonSource geoJsonSource;
    private ValueAnimator animator;
    public static double pre_lat,pre_long;
    public static Marker marker;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        Mapbox.getInstance(this, "*YOUR_KEY*");
        setContentView(R.layout.activity_main);

        Mapbox.getInstance(this, "");

        mapView = findViewById(R.id.mapView);
        //fetchData process = new fetchData();
        // process.execute();
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(new OnMapReadyCallback() 
            @Override
            public void onMapReady(@NonNull final MapboxMap mapboxMap) 
                MainActivity.this.mapboxMap = mapboxMap;
                mapboxMap.setCameraPosition(new CameraPosition.Builder()
                        .zoom(19)
                        .target(new 
       LatLng(24.987029999999997,67.056585))
                        .build());
                mapboxMap.setStyle(Style.DARK,
                        new Style.OnStyleLoaded() 
                            @Override
                            public void onStyleLoaded(@NonNull Style style) 
                               // enableLocationComponent(style);
                                // Create an Icon object for the marker to use

                                FirebaseDatabase database = FirebaseDatabase.getInstance();
                                String somi_id2 = "emp_samad";
                                DatabaseReference myRef3 = database.getReference("current");
                                GeoFire geoFire = new GeoFire(myRef3);
                                GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(24.987043333333336, 67.05663333333334), 10);
                                geoFire.getLocation("emp_samad", new LocationCallback() 
                                    @Override
                                    public void onLocationResult(String key, GeoLocation location) 
                                        if (location != null) 
                                            pre_lat = location.latitude;
                                            pre_long = location.longitude;
//                                            Location prevLoc = new Location(location.latitude,location.longitude);
//                                            Location newLoc =  ;
//                                            float bearing = prevLoc.bearingTo(newLoc) ;
                                            marker = mapboxMap.addMarker(new MarkerOptions()
                                                    .position(new LatLng(pre_lat,pre_long))
                                                    .icon(IconFactory.getInstance(MainActivity.this).fromResource(R.drawable.marker)));
                                            System.out.println(String.format("The location for key %s is [%f,%f]", key, location.latitude, location.longitude));
                                         else 
                                            System.out.println(String.format("There is no location for key %s in GeoFire", key));
                                        
                                    

                                    @Override
                                    public void onCancelled(DatabaseError databaseError) 

                                    
                                );
                                geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener() 
                                    @Override
                                    public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location) 
                                        System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
                                    

                                    @Override
                                    public void onDataExited(DataSnapshot dataSnapshot) 

                                    

                                    @Override
                                    public void onDataMoved(DataSnapshot dataSnapshot, GeoLocation location) 

                                    

                                    @Override
                                    public void onDataChanged(DataSnapshot dataSnapshot, GeoLocation location) 
                                        double lat = pre_lat;
                                        double lon = pre_long;

                                        LatLng pre_latlng = new LatLng(lat,lon);
                                        LatLng washington = new LatLng(location.latitude,location.longitude);



                                        ValueAnimator markerAnimator = ValueAnimator.ofObject(new TypeEvaluator<LatLng>() 

                                            @Override
                                            public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) 
                                                return new LatLng(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction, startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
                                            

                                        , new LatLng[]pre_latlng, washington);

                                        markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
                                            @Override
                                            public void onAnimationUpdate(ValueAnimator animation) 
                                                if (marker != null) 
                                                    marker.setPosition((LatLng) animation.getAnimatedValue());
                                                
                                            
                                        );

                                        markerAnimator.setDuration(7500);
                                        //markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
                                        //markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
                                        markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

                                        markerAnimator.start();

                                       /* if(marker!=null)
                                        
                                            //marker.remove();
                                            //marker.setPosition(new LatLng(location.latitude,location.longitude));
                                        
                                        System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
*/

                                       



                                    @Override
                                    public void onGeoQueryReady() 

                                    

                                    @Override
                                    public void onGeoQueryError(DatabaseError error) 

                                    
                                );
                            
                        );
            
        );
    

    @SuppressWarnings( "MissingPermission")
    private void enableLocationComponent(@NonNull Style loadedMapStyle) 
// Check if permissions are enabled and if not request
        if (PermissionsManager.areLocationPermissionsGranted(this)) 

// Get an instance of the component
            LocationComponent locationComponent = mapboxMap.getLocationComponent();

// Activate with options
            locationComponent.activateLocationComponent(
                    LocationComponentActivationOptions.builder(this, loadedMapStyle).build());

// Enable to make component visible
            locationComponent.setLocationComponentEnabled(true);

// Set the component's camera mode
            locationComponent.setCameraMode(CameraMode.TRACKING);

// Set the component's render mode
            locationComponent.setRenderMode(RenderMode.COMPASS);
         else 
            permissionsManager = new PermissionsManager(this);
            permissionsManager.requestLocationPermissions(this);
        
    

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
        permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    

    @Override
    public void onExplanationNeeded(List<String> permissionsToExplain) 
        Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
    



    @Override
    public void onPermissionResult(boolean granted) 
        if (granted) 
            mapboxMap.getStyle(new Style.OnStyleLoaded() 
                @Override
                public void onStyleLoaded(@NonNull Style style) 
                   // enableLocationComponent(style);
                
            );
         else 
            Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
            // finish();
        
    

    @Override
    @SuppressWarnings( "MissingPermission")
    public void onStart() 
        super.onStart();
        mapView.onStart();

    

    @Override
    public void onResume() 
        super.onResume();
        mapView.onResume();
    

    @Override
    public void onPause() 
        super.onPause();
        mapView.onPause();
    

    @Override
    public void onStop() 
        super.onStop();
        mapView.onStop();
    

    @Override
    public void onLowMemory() 
        super.onLowMemory();
        mapView.onLowMemory();
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        mapView.onDestroy();
    

    @Override
    public void onMapReady(@NonNull MapboxMap mapboxMap) 
    

    


    

你必须使用的是实现一个 geofire 库 地火实施

implementation 'com.firebase:geofire-android:3.0.0'

希望对你有帮助

【讨论】:

以上是关于geofire android 存储和检索位置并将其显示在地图上的主要内容,如果未能解决你的问题,请参考以下文章

如何从 GeoFire 中检索持续更新的位置数据并将其放在 Google 地图上?

如何使用geofire从firebase获取位置

Firebase GeoFire,从我当前位置检索具有特定半径的帖子

使用 geofire 仅检索 3 英里内的用户列表

使用 android Geofire 获取经度和纬度

如何在没有 Geofire 的情况下将位置对象保存在 Firebase 中?