Jac*_*son 15 iphone cocoa annotations objective-c mkmapview
有很多不好的方法可以解决我想要做的事情,但这似乎是"必须有更好的方法"的案例之一.
我在一个显示许多注释的iPhone应用程序中使用MKMapView.假装概念性的讨论,美国各州的每个城镇都有一个注释,所以屏幕上有一堆相当密集的注释.当用户缩小地图时,这些注释开始彼此紧缩,直到它们重叠并变得难以单独挑选.
我想做的是,在特定的注释密度(比如当任何注释重叠时),将这些注释合并到一个注释中,表明它包含了许多子注释(一些视觉指示符,"放大")你会看到更多的注释").
我可以在注释视图上调用CGRectIntersectsRect,但使用它似乎是一个N ^ 2问题 - 我将不得不迭代每个注释的每个注释.考虑这个伪代码:
FOR firstAnnotationView IN allAnnotationViews FOR secondAnnotationView in allAnnotationViews IF CGRectIntersectsRect(firstAnnotationView.frame, secondAnnotationView.frame) // found two overlapping annotations, consolidate them ENDIF ENDFOR ENDFOR
你可以看到为什么这会很慢,每次放大或缩小地图都必须运行!
那么你们如何在地图中检测重叠注释,并以精通业绩的方式智能地整合它们?
我会根据经度/纬度对您的注释进行分类,然后使用这些分类进行合并。基本想法如下所示:
#include <vector>
float minLongitude = 180.0f;
float maxLongitude = -180.0f;
float longitudeBinSize = 0.1; // Degrees
float minLatitude = -90.0f;
float maxLatitude = 90.0f;
float latitudeBinSize = 0.1; // Degrees
int numBinColumns = int((maxLongitude - minLongitude) / longitudeBinSize);
int numBinRows = int((maxLatitude - minLatitude) / latitudeBinSize);
void calcBinCoords(float longitude, float latitude, int &column, int &row) {
column = int((latitude - minLatitude) / latitudeBinSize);
row = int((longitude - minLongitude) / longitudeBinSize);
}
typedef std::vector<AnnotationView *> AnnotationViews;
void binAnnotations(NSArray *annotationViews, std::vector<AnnotationViews> &binnedAnnotations) {
binnedAnnotations.clear();
binnedAnnotations.resize(numBinColumns * numBinRows);
for (AnnotationView *annotationView in annotationViews) {
int column, row;
calcBinCoords(annotationView.longitude, annotationView.latitude, column, row);
binnedAnnotations[row * numBinColumns + column].push_back(annotationView);
}
}
Run Code Online (Sandbox Code Playgroud)
longitudeBinSize 和 latitudeBinSize 的值将是您在合并时要搜索的最大距离。一旦所有内容都在垃圾箱中,那么您的搜索问题只涉及在相邻垃圾箱中搜索候选值的列表。另外,由于您将在合并期间扫描阵列,因此实际上只需要检查您处理的每个垃圾箱的三个相邻垃圾箱——位于(列+1,行)的垃圾箱,位于(列,行+1)的垃圾箱),以及位于 (column+1,row+1) 的 bin。
您可以使用 NSMutableArrays 而不是 std::vector 作为垃圾箱,但听起来您有大量的项目需要处理,我怀疑 std::vector 会更快。但这只是我的偏好,可能根本不需要关心。如果您使用 ObjC 而不是 ObjC++ 那么您当然不能使用 std::vector 。
归档时间: |
|
查看次数: |
1905 次 |
最近记录: |