0

以下に関して、これら2つの質問のいずれかに答えられる人はいますか

1) MKOverlayPathView 内の zoomScale に従って動的にオーバーレイ オブジェクトのサイズを変更する場合、mkOverlay プロトコルをサポートするクラスが、zoomScale がどうなるかわからない場合に正しい boundingMapRect を返すようにするにはどうすればよいですか?

2) 小さすぎるboundingMapRectの副作用は何ですか?

オリジナル ....

私は 1 つの MKOverlayPathView を持つ MKMapView です。オーバーレイをマップに追加すると、パンとズームを行うと、下にあるマップのセクションがぼやけたり、場合によってはダウンロードされないままになります。オーバーレイ ビュー自体は問題なく、焦点が合っています。(前のズーム レベルから) あいまいなままになっているのはマップ データです。

オーバーレイが追加されていない場合、すべて正常に動作します。

MKOverlayPathView はサブクラス化され、ポイントとサイズの配列を持ちます。これらのポイントとサイズを使用して、塗りつぶされた円を特異なオーバーレイに描画して表示します。境界四角形は、それらが生成する円の半径を説明するすべての点の和集合から形成されます。

それで、私は何が欠けていますか?描画プロセスですか、boundingRect ですか、それとも何か他のものですか?

サンプルコード:

MapViewController コード

- (MKOverlayView *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MultiCluster class]]) {
        MKMultiClusterView *multiclusterView = [[MKMultiClusterView alloc] initWithOverlay:overlay];
        return multiclusterView;
    }

    return nil;
}

MultiCluster.h

@interface MultiCluster : NSObject <MKOverlay> {
    NSArray *_clusters;
    MKMapRect _boundingMapRect;
}

- (id)initWithClusters:(NSArray *)clusters;

@property (nonatomic, strong) NSArray *clusters;

@end

MultiCluster.m

@implementation MultiCluster

@synthesize clusters = _clusters;

- (id)initWithClusters:(NSArray *)clusters {
    if (self = [super init]) {
        _clusters = [clusters copy];

        NSUInteger clusterCount = [_clusters count];
        if (clusterCount) {
            _boundingMapRect = [[_clusters objectAtIndex:0] boundingMapRect];
            NSUInteger i;
            for (i = 1; i < clusterCount; i++) {
                _boundingMapRect = MKMapRectUnion(_boundingMapRect, [[_clusters objectAtIndex:i] boundingMapRect]);
            }
        }
    }

    return self;
}

- (void)setClusters:(NSArray *)clusters {
    _clusters = [clusters copy];
    NSUInteger clusterCount = [_clusters count];
    if (clusterCount) {
        _boundingMapRect = [[_clusters objectAtIndex:0] boundingMapRect];
        NSUInteger i;
        for (i = 1; i < clusterCount; i++) {
            _boundingMapRect = MKMapRectUnion(_boundingMapRect, [[_clusters objectAtIndex:i] boundingMapRect]);
        }
    }
}

- (MKMapRect)boundingMapRect {
    return _boundingMapRect;
}

- (CLLocationCoordinate2D)coordinate {
    return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(_boundingMapRect), MKMapRectGetMidY(_boundingMapRect)));
}

@end

MKMultiClusterView.h

@interface MKMultiClusterView : MKOverlayPathView {
    CGColorRef *colors;
}

@end

MKMultiClusterView.m

@implementation MKMultiClusterView

// Create a table of possible colors to draw a grid cell with
- (void)initColors
{
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
    colors = malloc(sizeof(CGColorRef) * NUM_COLORS);
    int i = 0;
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .588, .294, .78, OA }); // 1.00
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .784, .471, .82, OA }); // 0.77
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, 0, 0, OA }); // 0.59
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .392, 0, OA }); // 0.46
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .392, 0, OA }); // 0.35
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .784, 0, OA }); // 0.27
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, 1, .5, OA }); // 0.21
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .745, .941, .467, OA }); // 0.16
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .122, 1, .31, OA }); // 0.12
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .588, 1, .941, OA }); // 0.10
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .784, 1, 1, OA }); // 0.08
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .843, 1, 1, OA }); // 0.06
    colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .902, 1, 1, OA }); // 0.04
    colors[i] = CGColorCreate(rgb, (CGFloat[]){ .784, .784, .784, OA }); // 0.03
    CGColorSpaceRelease(rgb);
}

// Look up a color in the table of colors for a peak ground acceleration
- (CGColorRef)colorForSize:(int)value
{
    if (value > 3000) return colors[0];
    if (value > 2500) return colors[1];
    if (value > 2000) return colors[2];
    if (value > 1500) return colors[3];
    if (value > 1000) return colors[4];
    if (value > 540) return colors[5];
    if (value > 480) return colors[6];
    if (value > 420) return colors[7];
    if (value > 360) return colors[8];
    if (value > 300) return colors[9];
    if (value > 240) return colors[10];
    if (value > 180) return colors[11];
    if (value > 120) return colors[12];
    if (value <= 120) return colors[13];
    return NULL;
}

- (id)initWithOverlay:(id<MKOverlay>)overlay {
    if (self = [super initWithOverlay:overlay])
    {
        [self initColors];
    }
    return self;
}

- (CGPathRef)createPath:(Cluster *)cluster zoomScale:(MKZoomScale)zoomScale {
    CGMutablePathRef path = CGPathCreateMutable();
    // Calculate radius for circle in map pixels.    
    double fudge = 2;
    double viewWidth = 320;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
        fudge = 5;
        viewWidth = 768;
    }
    // Radius of circle in pixels.
    int radiusPixels = 10 + (fudge * log([cluster.members count]));
    fudge = 1/zoomScale;
    double radiusPoints = radiusPixels * fudge;
    double diameterPoints = radiusPoints * 2;

    // Center of circle in map points.
    CGPoint relativePoint = [self pointForMapPoint:MKMapPointForCoordinate(cluster.coordinate)];
    CGRect ellipseRect = CGRectMake(relativePoint.x - radiusPoints, 
                                    relativePoint.y - radiusPoints, 
                                    10000, 
                                    10000);
    CGPathAddEllipseInRect(path, NULL, ellipseRect);

    return path;
}

- (void)drawMapRect:(MKMapRect)mapRect
          zoomScale:(MKZoomScale)zoomScale
          inContext:(CGContextRef)context
{
    MultiCluster *multiCluster = (MultiCluster *)self.overlay;
    for (Cluster *cluster in multiCluster.clusters) {
        CGPathRef path = [self createPath:cluster zoomScale:zoomScale];
        if (path) {
            self.fillColor = [UIColor colorWithCGColor:[self colorForSize:[cluster.members count]]];
            [self applyFillPropertiesToContext:context atZoomScale:zoomScale];
            CGContextBeginPath(context);
            CGContextAddPath(context, path);
            CGContextDrawPath(context, kCGPathEOFill);
            CGPathRelease(path);
        }
    }
}

@end

MKMultiClusterView には、未使用の変数や、動的ではなく固定の円サイズなど、いくつかのテスト コードが含まれています。問題とは無関係です (円のサイズが固定されているか可変であるかは問題ではありませんが、問題は依然として存在します)。

さらにコードを含めたい場合はコメントしてください。サンプル プロジェクトとしてアップロードするか、この質問に関連するセクションを含める場所を見つけます。

同じコードの完全に静的な実装では問題は発生しません。修正は導入されたアルファで行われます。それで、問題があるのはboundingMapRectだと安全に言えますか?

4

1 に答える 1

1

アルファ成分を個々の円からレイヤー自体に移動しようとしましたか?

于 2012-02-17T13:57:31.067 に答える