Android - 显示折线

时间:2017-10-27 09:48:53

标签: android google-maps firebase firebase-realtime-database

我有两个活动的应用程序。在第一个活动中,用户可以在地图上设置两个标记,并在两个标记之间绘制路径。在第二个活动中,我想显示第一个活动中绘制的所有路径。为此,我在Firebase实时数据库中保存路径的航点,并在第二个活动中检索数据。

截至目前,第二个活动仅显示数据库中的一个路径。我想要做的是显示用户在第二个活动中的第一个活动(保存在数据库中)中所做的所有路径。我假设我必须做一些循环才能做到这一点。关于如何做到这一点的任何想法?

POJO课程 - 路线:

public class Route {

    private ArrayList<Location> locations;

    public Route() {
    }

    public ArrayList<Location> getLocations() {
        return locations;
    }

    public void setLocations(ArrayList<Location> locations) {
        this.locations = locations;
    }
}

POJO课程 - 地点:

public static class Location {
    private Double latitude;
    private Double longitude;

    public Location() {
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }
}

我的数据库:

enter image description here

如何检索数据并添加折线到地图:

  userRef.child(sharedPreferences.getString("school", null)).child("routes").child(sh.getString("key", null)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Route route = dataSnapshot.getValue(Route.class);
            for (Location location : route.getLocations()) {
                double lat = location.getLatitude();
                double lng = location.getLongitude();
                position = new LatLng(lat, lng);
                points.add(position);
            }
        }


 PolylineOptions lineOptions = new PolylineOptions();
    for (LatLng point : points) {
        lineOptions.add(point);
    }
    lineOptions.width(12);
    lineOptions.clickable(true);
    lineOptions.color(Color.RED);
    mMap.addPolyline(lineOptions);

1 个答案:

答案 0 :(得分:1)

在您当前的示例中,您将侦听器附加到$school/routes下的单个节点,因此它只会检索该节点。

如果您需要一次检索所有路由,则需要将监听器附加到routes节点并单独遍历子节点。来自documentation on working with lists of data

  

将ValueEventListener附加到数据列表会将整个数据列表作为单个DataSnapshot返回,然后您可以循环访问以访问各个子项。

这样的事情应该可以胜任:

public void drawAllRoutes() {
    userRef.child(sharedPreferences.getString("school", null)).child("routes").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                Route route = child.getValue(Route.class);
                drawRoute(route);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

public void drawRoute(Route route) {
    PolylineOptions lineOptions = new PolylineOptions();

    for (Location location : route.getLocations()) {
        double lat = location.getLatitude();
        double lng = location.getLongitude();
        lineOptions.add(new LatLng(lat, lng));
    }

    lineOptions.width(12);
    lineOptions.clickable(true);
    lineOptions.color(Color.RED);

    mMap.addPolyline(lineOptions);
}

drawAllRoutes()方法将侦听器附加到$school/routes节点,这将为您提供该节点下列表的DataSnapshot,并在{{DataSnapshot#getChildren()中提供每个子节点1}}。然后,您可以迭代这些子项以分别绘制每条折线。

我还将路由绘制逻辑移动到drawRoute()方法中,这样它就可以在地图上绘制Route的任何实例,无论这个Route对象是如何创建的

drawRoute()方法使用mMap变量 - 即视图中的GoogleMap个实例 - 因此您只能在地图显示后调用drawAllRoutes()方法准备就绪:

private GoogleMap mMap;

// ...

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

    // ...

    drawAllRoutes();
}