在地图上绘制时减少多边形

发布于 2024-12-03 04:35:56 字数 402 浏览 2 评论 0原文

今天我们在 MKMapView 上绘制多边形。我们使用以下伪代码来绘制多边形。

CGContextMoveToPoint
CGContextAddLineToPoint
CGContextAddLineToPoint
CGContextAddLineToPoint
CGContextClosePath
CGContextFillPath

结果可能如下所示:

data table

我们一次获取一行数据,颜色赋予基于我们收到的数据的单元格。有没有一种方法或多边形缩减算法可以将所有相同颜色的多边形组合在一起(假设它们相交)以给我一个大多边形?所以在这个例子中,所有的红色都是一个大多边形。

Today we are drawing polygons on a MKMapView. We use the following pseudocode to draw polygons.

CGContextMoveToPoint
CGContextAddLineToPoint
CGContextAddLineToPoint
CGContextAddLineToPoint
CGContextClosePath
CGContextFillPath

The result could potentially look like this:

data table

We get the data one row at a time, the colors are given to the cell based on the data we receive. Is there a way or polygon reduction algorithms that would group all the same colored polygons together (assuming they intersect) to give me one big polygon? So in this example all the reds would one big polygon.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

未蓝澄海的烟 2024-12-10 04:35:57

CoreGraphics 可以原生处理凹多边形,因此问题的主要部分是洪水填充,以计算出填充区域的边界。

即兴思考,一个简单的算法可能是将边缘标志与每个单元相关联。如果该边是多边形外部的一部分,则设置边标志。标志由在该边缘相遇的两个单元共享。

选择任意单元格并设置所有四个边缘标志。重置所有其他单元上的边缘标志。然后编写一个递归方法,对于每个单元格:

  • 依次测试每个边缘标志是否已设置;
  • 如果设置了标志,则检查共享该边缘的单元格是否具有相同的颜色;
  • 如果是,则反转该单元的边缘标志并递归到它。

反转与“连接到您已知的旁边的任何单元格,将我们尚未查看的单元格旁边的任何边缘设置为边界的一部分”相同。

递归可能会深入数百个项目,因此可能值得保留一个单元格列表来考虑并将其添加到该列表中,而不是递归,就像实现问题一样。您访问单元格的顺序并不重要,因此结果应该是相同的。

一旦您用完可访问的单元格,您就可以通过从任何标记的边缘绕着它走来重建整个边界。唯一稍微复杂的地方是当您遇到单元格的对角线时,例如黄色和绿色单元格在第四列和第五列之间接触的位置。您需要应用从当前边移动到下一条边的逻辑,该边与其共享顶点和正确颜色的单元格。

CoreGraphics can handle concave polygons natively, so the main part of the problem is a flood fill to work out the boundaries of the filled area.

Thinking extemporaneously, a naive algorithm could be to associate edge flags with each cell. An edge flag is set if that edge is part of the exterior of the polygon. Flags are shared by the two cells that meet at that edge.

Pick any cell and set all four edge flags. Reset the edge flags on all other cells. Then write a recursive method that, for each cell:

  • tests in turn whether each edge flag is set;
  • if a flag is set, checks whether the cell that shares that edge is of the same colour;
  • if it is, inverts the edge flags of that cell and recurses to it.

The inversion is the same as saying "connect to any cells you're known to be next to, set any edges that are next to cells we haven't looked at yet to be part of the boundary".

The recursion could get hundreds of items deep, so it might be worth keeping a list of cells to consider and adding to that list rather than recursing, just as a matter of implementation. It shouldn't matter what order you visit the cells in, so the outcome should be the same.

Once you've run out of cells to visit, you can reconstruct the entire boundary by walking around it from any flagged edge. The only slight complexity will be when you get to a diagonal meeting of cells, like where the yellow and green cells touch between your fourth and fifth columns. You need to apply the logic that you move from the current edge to the next one with which it shares both a vertex and a cell of the correct colour.

琴流音 2024-12-10 04:35:57

这是矩形绘制函数的工作,而不是路径绘制函数的工作。请参阅 CGContextFillRect()、CGContextStrokeRect() 和 CGContextFillRects()。他们会快得多。

This is a job for the rectangle drawing functions, not the path drawing functions. See CGContextFillRect(), CGContextStrokeRect() and CGContextFillRects(). They will be much faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文