通过实时纬度和时间更改标记位置Firebase数据库中的lang,未添加新的一个标记 [英] Change marker position by Realtime lat & lang in Firebase database without added new one marker

查看:75
本文介绍了通过实时纬度和时间更改标记位置Firebase数据库中的lang,未添加新的一个标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的实时Firebase数据库

My realtime Firebase database

我会尝试在某些时候更改许多拉特朗的位置,例如超级汽车中的汽车, 但是,当我更改lat或lang或两者都更改时,这不会更改标记的位置,而是会重新创建标记.我想例如在实时数据库中更改纬度时,标记也根据该纬度的值进行更改

I try to change position for many lat langs at some time like cars in uber, but when I change lat or lang or both this don't change the position of marker but its make anew marker. I want when lat for example is changed in realtime database the markers also changed based on the value of that lat

我尝试制造条件

`if (marker != null) 
    setPosition 
 else "marker == null"` 
    add new marker 

但是问题是我有> 1个标记,因此此解决方案仅在标记上显示我一个标记,因为标记!= null

but the problem is I have >1 markers so that this solution is display me on the map one marker only because marker != null

public class Map extends FragmentActivity implements OnMapReadyCallback {
FirebaseDatabase database;
DatabaseReference myRef;
GoogleMap mMap;
MarkerOptions options;
Marker mCurrLocationMarker;
LatLng ll;
model save;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

  @Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    database = FirebaseDatabase.getInstance();
    myRef = database.getReference("user");

    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {

                Double lang = ds.child("lang").getValue(Double.class);
                Double lat = ds.child("lat").getValue(Double.class);
                save = new model(lat, lang);
                ll = new LatLng(save.getLat(), save.getLang());

                mCurrLocationMarker = mMap.addMarker(options
                        .position(ll));

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

我希望在Firebase中更改实时lat和lang时会更改标记的位置,但是结果会创建另一个标记.

I expected the marker's position was changed when I change real time lat and lang in firebase, but the result is created another marker.

推荐答案

在我对其他答案的评论之后,这是我根据您的问题提出的建议.

Following from my comments on other answers, here is what I've come up with based on your question.

此代码将在地图上显示多个标记,但数据库中/users下每个ID仅一个标记.如果特定ID的位置发生了变化,则其关联的标记将被移动,而不会影响地图上的其他标记.

This code will show multiple markers on the map, but only one marker for each ID under /users in the database. If the location for a particular ID changes, it's associated marker will be moved without affecting the other markers on the map.

警告:以下代码将实时更新您的地图.您可以缓存新标记的位置,然后仅每2-5秒更新一次,具体取决于数据更改的频率.

Warning: The below code will update your map in real-time. You may which to cache the new marker locations and only update them once every 2-5 seconds or so depending on your how frequently your data changes.

在深入研究代码之前,请注意以下几点:

Some quick notes before diving into the code:

  • 每个标记都在名为mNamedMarkers的映射下链接到数据库中的字符串ID.
  • 由于未提供model且似乎无关紧要,因此我在下面的代码中将其省略了.
  • 我不确定您是否来自日耳曼语系,但是lng是经度的缩写,在这种情况下不是"lang".我还将更改您的数据库条目以使用lng而不是lang/long/longitude/etc(这样可以节省空间并消除混乱).
  • 在下面的代码中,我添加了getMarkerOptions(key),这是为了使您可以添加代码以根据其ID为每个标记获取不同的图像,标题和文本.目前,它将为每个标记生成相同的数据.
  • 我为每个函数添加了Javadoc标记,以总结每个函数的作用.
  • 有两个待开发的待办事项.
  • Each marker is linked to it's string ID in the database under a Map called mNamedMarkers.
  • As model was not provided and seems irrelevant, I have omitted it from the code below.
  • I'm not sure if you are coming from a Germanic background, but lng is short for Longitude, not "lang" in this context. I would also change your database entries to use lng rather than lang/long/longitude/etc (it saves space & eliminates confusion).
  • In the code below, I've added getMarkerOptions(key), this is so that you can add code to get different images, titles, and text for each marker based on it's ID. Currently it will produce the same data for each marker.
  • I've added Javadoc mark-up for each function to summarize what each does.
  • There are a couple of TODOs for further development.

这是代码:

public class Map extends FragmentActivity implements OnMapReadyCallback {
    FirebaseDatabase database;
    DatabaseReference userLocationsRef;
    GoogleMap mMap;

    Map<String, Marker> mNamedMarkers = new HashMap<String,Marker>();

    ChildEventListener markerUpdateListener = new ChildEventListener() {

            /**
             * Adds each existing/new location of a marker.
             *
             * Will silently update any existing markers as needed.
             * @param dataSnapshot  The new location data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Adding location for '" + key + "'");

                    Double lng = ds.child("lang").getValue(Double.class);
                    Double lat = ds.child("lat").getValue(Double.class);
                    LatLng location = new LatLng(lat, lng);

                    Marker marker = mNamedMarkers.get(key);

                    if (marker == null) {
                        MarkerOptions options = getMarkerOptions(key);
                        marker = mMap.addMarker(options.position(location));
                        mNamedMarkers.put(key, marker);
                    } else {
                        // This marker-already-exists section should never be called in this listener's normal use, but is here to handle edge cases quietly.
                        // TODO: Confirm if marker title/snippet needs updating.
                        marker.setPosition(location);
                    }
            }

            /**
             * Updates the location of a previously loaded marker.
             *
             * Will silently create any missing markers as needed.
             * @param dataSnapshot  The new location data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Location for '" + key + "' was updated.");

                    Double lng = ds.child("lang").getValue(Double.class);
                    Double lat = ds.child("lat").getValue(Double.class);
                    LatLng location = new LatLng(lat, lng);

                    Marker marker = mNamedMarkers.get(key);

                    if (marker == null) {
                        // This null-handling section should never be called in this listener's normal use, but is here to handle edge cases quietly.
                        Log.d(TAG, "Expected existing marker for '" + key + "', but one was not found. Added now.");
                        MarkerOptions options = getMarkerOptions(key); // TODO: Read data from database for this marker (e.g. Name, Driver, Vehicle type)
                        marker = mMap.addMarker(options.position(location));
                        mNamedMarkers.put(key, marker);
                    } else {
                        // TODO: Confirm if marker title/snippet needs updating.
                        marker.setPosition(location);
                    }
            }

            /**
             * Removes the marker from its GoogleMap instance
             * @param dataSnapshot  The removed data
             */
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Location for '" + key + "' was removed.");

                    Marker marker = mNamedMarkers.get(key);
                    if (marker != null)
                        marker.remove()
            }

            /**
             * Ignored.
             * @param dataSnapshot  The moved data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
                    // Unused
                    Log.d(TAG, "Priority for '" + dataSnapshot.getKey() "' was changed.");
            }

            /**
             * Error handler when listener is canceled.
             * @param databaseError  The error object
             */
            @Override
            public void onCancelled(DatabaseError databaseError) {
                    Log.w(TAG, "markerUpdateListener:onCancelled", databaseError.toException());
                    Toast.makeText(mContext, "Failed to load location markers.", Toast.LENGTH_SHORT).show();
            }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_map);
            // Obtain the SupportMapFragment and get notified when the map is ready to be used.
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                            .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
    }

    /**
     * Waits for the map to be ready then loads markers from the database.
     * @param googleMap  The GoogleMap instance
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;

            database = FirebaseDatabase.getInstance();
            userLocationsRef = database.getReference("user");

            userLocationsRef.addChildEventListener(markerUpdateListener);



            // later when the activity becomes inactive.
            // userLocationsRef.removeEventListener(markerUpdateListener)
    }

    /**
     * Retrieves the marker data for the given key.
     * @param key  The ID of the marker
     * @return A MarkerOptions instance containing this marker's infoormation
     */
    private MarkerOptions getMarkerOptions(String key) {
        // TODO: Read data from database for the given marker (e.g. Name, Driver, Vehicle type)
        return new MarkerOptions().title('Location placeholder').snippet('Update this with marker information');
    } 
}

这篇关于通过实时纬度和时间更改标记位置Firebase数据库中的lang,未添加新的一个标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆