【问题标题】:OSMDroid PathOverlay drawing is corrupted at high zoom levelsOSMDroid PathOverlay 绘图在高缩放级别时损坏
【发布时间】:2012-02-14 08:08:55
【问题描述】:

我正在使用 OSMdroid 来实现一个地图应用程序。

我已经实现了一个自定义 MapTileProvider,它使用允许缩放级别高达 22 的图块源。

默认的 MAPNIK 提供程序只允许缩放到 18 级。

问题是任何 PathOverlay 实例在缩放级别 19 之前都可以完美绘制,但随后 在缩放级别 20-22 时未正确绘制。看起来有人用橡皮擦擦掉了路径长度的 90% 以上(见下面的屏幕截图)。

我已逐步完成 PathOverlay 的 draw() 方法,并且 exerything 似乎 计算正确(中间点对于 ZoomLevel 22 显示正确,然后 XY 投影除以 22-ZoomLevel获取当前屏幕坐标)。

谁能提供一些关于问题是什么以及如何解决它的见解?

如果我使用 Cloudmade 小图块调用 MapView,也会发生同样的事情,它允许放大到 20 级并且是“内置”osmDroid 图块提供程序类。

    //mMapTileProvider = new HighResMapTileProvider(this);
    mMapTileProvider = new MapTileProviderBasic(this,TileSourceFactory.CLOUDMADESMALLTILES);
    mMapView = new MapView(this, 256, mResourceProxy,mMapTileProvider);

所以问题似乎不在于 tile 源或提供程序,而在于画布绘制方法。有关如何解决此问题的任何想法?

在 zoomLevel 19 我可以很好地看到我的路径:

但这是下一个缩放级别的相同路径:

【问题讨论】:

  • 你可能会感兴趣,我有一个类似的问题,我无法真正解决这里描述的问题:stackoverflow.com/questions/8115394/…
  • 模拟器或真实硬件或两者兼而有之。如果 4.0.3 尝试关闭硬件加速。
  • 这是关闭了硬件加速。如果我尝试打开它,我会收到大量 UnsupportedOperation 异常。
  • 我发现这实际上是 OSMdroid 项目中记录的问题 - Issue 221

标签: android canvas paint osmdroid stroke


【解决方案1】:

我找到了解决方法。这并不理想,但确实有效。

首先,如果我添加一个 canvas.drawCircle(screenPoint1.x, screenPoint1.y, 5, cpaint);

我看到了 PathOverlay 的 draw() 方法,所以我知道坐标至少计算正确。

所以问题似乎与Android中底层的line draw方法有关。

经过反复试验,我发现将 PathOverlay 的 Paint 对象的 STROKE WIDTH 设置为 0.0 可以解决问题,但线条显然只有 1 个像素宽。

在 PathOverlay.draw() 中添加对当前缩放级别的检查以设置笔触宽度将保持级别

我注意到的其他一些事情:

  • 圆圈在缩放级别 21 和 22 时变为正方形。这强烈表明在将非常大的 (x,y) 坐标传递给 Path.lineTo / canvas.drawCircle 等时存在一些浮点精度问题,例如mPath.lineTo(131000001,38000001)
  • 设置描边宽度表示,5 种最高可缩放到 21 级,但同样的问题再次出现在 22 级

【讨论】:

  • 我今天早些时候做了一点“代码潜水”。似乎较低级别的(Android)代码将浮点转换为定点表示(32 位整数)。它通过乘以“(1
【解决方案2】:

更新:这已在 osmdroid 3.0.9 中修复。

原答案:
这个问题似乎植根于Android。我相信这是由于将视图滚动到较大偏移量时发生的舍入误差(可能是由于使用了 SKScalar)。可以通过创建一个带有 Activity 和视图的新 android 项目来隔离这个 bug:

  1. 从原点的视图开始,还没有滚动偏移。
  2. 在画布上画一个圆圈:canvas.drawCircle(screenCenterX, screenCenterY, 100, mPaint)
  3. 将视图滚动到一个大数字:mainView.scrollTo(536870912, 536870912)
  4. 在画布上画一个圆圈:canvas.drawCircle(newScreenCenterX, newScreenCenterY, 100, mPaint)

第一个圆圈绘制正常,第二个绘制扭曲。如需进一步的证据,请尝试在 0 lat/0 long 附近绘制路径并放大 - 注意不再出现失真。

我将使用一些可能的解决方案解决方法来更新 osmdroid 票证。

【讨论】:

    【解决方案3】:

    我很确定这是因为默认的 PathOverlay 仅在视图中的点之间绘制线。如果该点位于当前视图之外,则不绘制线段。在较低的缩放级别下,您只是看不到超出视图的线部分没有显示,因为所有部分都很小。

    我认为您有两个选择。

    简单但可能不是最好的方法是将更多点放入路径中,那么至少问题会不那么明显。这是否是一个好主意将取决于您已经拥有多少分。

    正确的解决方案是扩展类并执行您自己的绘制方法,然后将离开视图的线段剪辑到视图边缘。理想情况下,您会将您的代码贡献回源代码。

    【讨论】:

    • 我可能没有解释清楚。如果放大从 18->19 级的路径,我会看到我仍然希望看到的路径部分。从 19->20 缩放,我希望看到的部分路径消失了;但不完全,这里和那里零星地画了几个点。在这些缩放级别上绘制的路径上并不是只有一个点。有几十个。
    【解决方案4】:

    我有同样的问题,我在这里发布了一个关于 OSMDroid 的错误:

    http://code.google.com/p/osmdroid/issues/detail?can=2&start=0&num=100&q=221&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=221

    我不确定这是 OSMDroid 的问题还是只是画布太大的问题。

    其他解决方法是在新的较小画布(当前可见 mapView 的大小)上绘图,并在大画布的左上角使用 drawBitmap。请记住不要每次绘制都创建新的位图 - 因为它很昂贵。

    所有形状都绘制得非常好,但我正在努力解决其他问题,即在级别 > 18 中平移不平滑。您可以看到,当您平移地图时,它并没有像在级别

    【讨论】:

    • 我已经看到了这个问题并投了赞成票,但我也不是 100% 相信问题出在 osmdroid 上。我在 Zoom 21 看到,即使是小人周围的精确度圈都被扭曲了。如果您不介意将线条绘制为 1 像素宽,则绝对可以使用我上面描述的笔画宽度修复。
    【解决方案5】:

    我同意这是与 OSMDROID 相关的错误,因为我使用 Google MapView 获得了相同的 DrawPath 功能(缩放级别 21 和 22)。我希望他们能够解决这个问题。

    【讨论】:

    • Google MapView 使用 OpenGL 而不是像 osmdroid 这样的画布绘图。
    【解决方案6】:

    为了解决这个问题,我们需要实现线裁剪算法。 通过使用地图视口进行裁剪,路径会添加更多顶点。 因此,它将在大缩放级别正确绘制。

    【讨论】:

      猜你喜欢
      • 2014-04-12
      • 2014-01-03
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多