23

iPhone Map Kitクラスターのピンポイントについて:

マップに表示したい数千のマークがありますが、処理するには多すぎるため、それらをクラスター化したいと考えています。

利用可能なフレームワークや概念実証はありますか? これは可能ですか、それともすでに行われていますか?

4

8 に答える 8

13

REVClusterMapを使用してクラスター化できます

于 2011-07-18T05:54:44.360 に答える
8

注:これは私が提携している商用製品ですが、この問題を解決します。

いくつかのアプリでこの問題を解決し、再利用可能なフレームワークに抽出することにしました。これはSuperpinと呼ばれ、注釈ストレージにクアッドツリーを内部的に使用し、グリッドベースのクラスタリングを実行する(商用、ライセンス料は149ドル)iOSフレームワークです。アルゴリズムは非常に高速で、含まれているサンプルアプリは世界の空港(3万以上の注釈)を表示しており、3GiPhoneで非常にスムーズに実行されています。

于 2011-05-02T14:18:01.413 に答える
6

ここで提案されている他のものを試してみましたが、最も効果的なOCMapViewも見つかりました。

無料で、注釈を簡単にグループ化できます。これは私が必要としていたものです。Revolverよりも少し新しく、より更新されており、私にとっては実装が簡単です.

于 2013-02-05T21:05:55.380 に答える
6

これはチェーンソーを使って芝生を刈るのと少し似ているかもしれませんが、これはアルゴリズムの概要 からの抜粋です

KD ツリーを作成しています...

public class KDFactory {
  // Known comparators for partitioning points along dimensional axes.
  private static Comparator<IMultiPoint> comparators[ ] ;
  // Recursively construct KDTree using median method on input points.
  public static KDTree generate (IMultiPoint [ ] points) {
    if (points. length == 0) { return null; }
    // median will be the root.
    int maxD = points[ 0] . dimensionality( );
    KDTree tree = new KDTree(maxD) ;
    // Make dimensional comparators that compare points by ith dimension
    comparators = new Comparator[ maxD+1] ;
    for (int i = 1; i <= maxD; i++) {
      comparators[ i] = new DimensionalComparator(i) ;
    }
    tree. setRoot(generate (1, maxD, points, 0, points. length-1) ) ;
    return tree;
  }

  // generate the node for the d-th dimension (1 <= d <= maxD)
  // for points[ left, right]
  private static DimensionalNode generate (int d, int maxD,
                                           IMultiPoint points[ ] ,
                                           int left, int right) {
    // Handle the easy cases first
    if (right < left) { return null; }
    if (right == left) { return new DimensionalNode (d, points[ left] ) ; }
    // Order the array[ left, right] so the mth element will be the median
    // and the elements prior to it will all be <=, though they won' t
    // necessarily be sorted; similarly, the elements after will all be >=
    int m = 1+(right-left) /2;
    Selection. select(points, m, left, right, comparators[ d] ) ;
    // Median point on this dimension becomes the parent
    DimensionalNode dm = new DimensionalNode (d, points[ left+m-1] ) ;
    // update to the next dimension, or reset back to 1
    if (++d > maxD) { d = 1; }
    // recursively compute left and right sub-trees, which translate
    // into ' below' and ' above' for n-dimensions.
    dm. setBelow(maxD, generate (d, maxD, points, left, left+m-2) ) ;
    dm. setAbove(maxD, generate (d, maxD, points, left+m, right) ) ;
    return dm;
  }
}

最近傍を最良に見つける: O(log n) 最悪 O(n)

// method in KDTree
public IMultiPoint nearest (IMultiPoint target) {
  if (root == null) return null;
  // find parent node to which target would have been inserted. This is our
  // best shot at locating closest point; compute best distance guess so far
  DimensionalNode parent = parent(target) ;
  IMultiPoint result = parent. point;
  double smallest = target. distance(result) ;
  // now start back at the root, and check all rectangles that potentially
  // overlap this smallest distance. If better one is found, return it.
  double best[ ] = new double[ ] { smallest };
  double raw[ ] = target. raw( );
  IMultiPoint betterOne = root. nearest (raw, best) ;
  if (betterOne ! = null) { return betterOne; }
  return result;
}

// method in DimensionalNode. min[ 0] contains best computed shortest distance.
IMultiPoint nearest (double[ ] rawTarget, double min[ ] ) {
    // Update minimum if we are closer.
    IMultiPoint result = null;
    // If shorter, update minimum
    double d = shorter(rawTarget, min[ 0] ) ;
    if (d >= 0 && d < min[ 0] ) {
      min[ 0] = d;
      result = point;
    }
    // determine if we must dive into the subtrees by computing direct
    // perpendicular distance to the axis along which node separates
    // the plane. If d is smaller than the current smallest distance,
    // we could "bleed" over the plane so we must check both.
    double dp = Math. abs(coord - rawTarget[ dimension-1] ) ;
    IMultiPoint newResult = null;
    if (dp < min[ 0] ) {
      // must dive into both. Return closest one.
      if (above ! = null) {
        newResult = above. nearest (rawTarget, min) ;
        if (newResult ! = null) { result = newResult; }
      }
      if (below ! = null) {
        newResult = below. nearest(rawTarget, min) ;
        if (newResult ! = null) {  result = newResult; }
      }
    } else {
      // only need to go in one! Determine which one now.
      if (rawTarget[ dimension-1] < coord) {
        if (below ! = null) {
          newResult = below. nearest (rawTarget, min) ;
        }
      } else {
        if (above ! = null) {
          newResult = above. nearest (rawTarget, min) ;
        }
      }
      // Use smaller result, if found.
      if (newResult ! = null) { return newResult; }
    }
    return result;
  }

ウィキペディアの KD ツリーの詳細

于 2010-01-13T16:39:52.440 に答える
1

最近、MapKit を使用してアノテーション クラスタリングを実装する必要がありました。ユースケースによっては、上記のソリューションが適切です。FBAnnotationClustering (Objective-C) は無料で、多くの星があり、github での問題がほとんどなかったため、最終的には FBAnnotationClustering (Objective-C) を使用することになりました。

https://github.com/infinum/FBAnnotationClustering

私が取り組んでいたアプリは非常にマップ中心であったため、FBAnnotationClustering を Swift に変換することは理にかなっています。このアプローチに関するブログ投稿には、github のサンプル プロジェクトへのリンクが含まれています。

http://ribl.co/blog/2015/05/28/map-clustering-with-swift-how-we-implemented-it-into-the-ribl-ios-app/

于 2015-06-29T17:50:05.300 に答える
1

概念実証は、オフライン マップ アプリ「OffMaps」です ;)

http://itunes.apple.com/us/app/offmaps/id313854422?mt=8

于 2010-01-14T20:23:12.907 に答える
-1

Foto Brisko (iTunes リンク) がこれを行っていると思います。
そのための Cocoa Touch フレームワークはないと思います。

于 2010-01-12T09:06:41.280 に答える