如何使用折线的setTag在Google地图中保存自定义数据

时间:2018-12-29 12:04:03

标签: android google-maps google-maps-markers google-polyline

当我单击折线时,我希望时间(自定义对象)显示在该特定纬度位置。

实现折线的代码

PolylineOptions lineOptions = new PolylineOptions().width(7).color(Color.BLACK).geodesic(true);

for (int i = 0; i < points.size(); i++) {
    LatLng latLng1 = new LatLng(Double.parseDouble(points.get(i).getmLatitude()), Double.parseDouble(points.get(i).getmLongitude()));
    lineOptions.add(latLng1);
}

if (mPolyline != null) {
    mPolyline.remove();
}

mPolyline = mMap.addPolyline(lineOptions);
mPolyline.setClickable(true);

for (int i = 0; i < points.size(); i++) {
//setting tags to be used on ployline click                   
mPolyline.setTag(points.get(i).getTime());
}

List<PatternItem> pattern = Arrays.asList(
        new Gap(15), new Dash(15), new Gap(15));
mPolyline.setPattern(pattern);
mPolyline.setJointType(JointType.ROUND);

现在,当我单击折线时,我只会得到一个标签,该标签对所有标签都是相同的。我想要每个与经纬度相关的折线位置的唯一标签(自定义对象)

mMap.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
    @Override
    public void onPolylineClick(Polyline polyline) {
        Toast.makeText(mContext, (String) polyline.getTag(), Toast.LENGTH_SHORT).show();
    }
});

感谢您的贡献:)

编辑

 mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        boolean isOnRoute = PolyUtil.isLocationOnPath(latLng, lineOptions.getPoints(), false, 25);

        if (isOnRoute) {              
            for (LocationVo mCoordinates : points) {
              double distanceInMeters =  SphericalUtil.computeDistanceBetween(latLng, mCoordinates.getmLatLong());
                boolean isWithin50m = distanceInMeters < 50;
                if (isWithin50m) {
                    Toast.makeText(mContext, mCoordinates.getTime(), Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        }
    }
});

不是我所有的折线都符合条件,并且单击时不显示吐司

1 个答案:

答案 0 :(得分:1)

公差为25米时,您将沿着两侧25米处的每个路径段定义一条走廊。因此,实施后,所有这些告诉您的是,点击点位于路径中居中的走廊中的某处,或者实际上,他们已经点击了折线并存在一定的错误空间。

您遇到的问题是,假设您始终位于某个点的50米以内-这是不正确的,而且也不是我所能告诉的。根据定义,一旦isOnRoute为真,您就一直想找到一个点,因为根据定义,它们已经单击了折线;通过简单地计算从点击点到所有折线点的 all 距离并确定最短距离(一个简单的循环),可以(有效地)完成此操作 带有min逻辑);然后用这一点做烤面包。

现在,如果您真的想限制被认为是“成功”的点击,一次成功的点击既在“折线”上,又在“接近一个点”,那么您的距离检查将使用添加一些可接受的值-实际上,无论距离检查是什么,这实际上都会在尺寸为50米(25 x 2)的每个点周围定义一个“框”。请注意,这与仅检查每个点周围的半径圆是不同的,除非所需圆的 radius 等于折线公差。

(另一个琐碎的点-使用false进行测地线然后计算球面距离时的混合测量系统-但对您的实现来说应该不是问题。)(如果有帮助,我稍后会添加图片。 )

修改摘要:“检查用户是否沿折线单击”和“确定沿线的最近点”并“显示该点的吐司”。

因此,在isOnRoute为真之后进行以下修改:

        LocationVo closestPoint = null;
        double minDist = -1;
        for (LocationVo mCoordinates : points) {
          double distanceInMeters =  SphericalUtil.computeDistanceBetween(latLng, mCoordinates.getmLatLong());
          if (minDist < 0 || distanceInMeters < minDist) {
             minDist = distanceInMeters;
             closestPoint = mCoordinates;
          }
        }
        if (closestPoint != null) {
            Toast.makeText(mContext, closestPoint.getTime(), Toast.LENGTH_SHORT).show();
        }

要实现上述围绕每个要点的“框”,请修改一个条件:

          if ((distanceInMeters < MAX_DISTANCE_FROM_POINT) && (minDist < 0 || distanceInMeters < minDist)) {

请注意,这意味着在某些情况下,即使他们沿多段线单击,也不会吐司。