【问题标题】:How to use setTag of polyline to save custom data in Google Maps如何使用折线的 setTag 在谷歌地图中保存自定义数据
【发布时间】:2019-05-26 22:01:02
【问题描述】:

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

实现折线的代码

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);

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

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;
                }
            }
        }
    }
});

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

【问题讨论】:

  • 你不能用标签到达那里 - 你最好使用onMapClickListener 并计算最近点,如果在points 的容差显示时间内。请参阅 android-maps-utils 获取 PolyLine.isLocationOnPath 和 SphericalUtil.computeDistanceBetween。不幸的是,polyLineListener 没有给出点击点,否则你可以在那里进行计算。
  • @Andy 确切地说已经有 18 天了,我能够通过关注您的评论来显示折线单击的时间谢谢!不过我有一个问题,我比较从 SphericalUtil.computeDistanceBetween 得到的距离小于 50 米,并不是我所有的折线点击都显示时间请检查我已经编辑了我的问题

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


【解决方案1】:

在 25 米的容差下,您将沿着每条路径段定义一条走廊,两侧各 25 米。因此,在实施时,所有这些都告诉您点击点位于以路径为中心的走廊中的某处 - 或者实际上他们点击了折线,但仍有一定的错误空间。

您遇到的问题是您假设您将始终在一个点的 50 米范围内 - 这是不正确的,也不是您想要的,尽我所能。根据定义,一旦isOnRoute 为真,您总是希望找到一个点,因为根据定义,他们点击了折线;这是通过简单地计算从点击点到所有折线点的 all 距离并确定最短距离(一个简单的循环)来完成的(效率低下) 使用min 逻辑);然后将这一点用于您的吐司。

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

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

修改摘要:“检查用户是否沿折线点击”和“确定沿线最近的点”和“为该点显示一些 toast”。

所以在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)) {

请注意,这意味着在某些情况下,即使他们沿着折线单击,您也不会得到祝酒。

【讨论】:

  • 这么漂亮的答案
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 2015-01-28
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-05
相关资源
最近更新 更多