1

GMSPolylineプロトコルcolorがストロークの色のプロパティを既に定義していることがわかりますが、ポリゴンの内側を (理想的には透明度で) シェーディングする方法はありますか? MKPolygonと友達に相当する Google マップを探しています。

4

2 に答える 2

2

次のような方法があります。

ポリゴンの例

アプローチはかなり単純です。

  • オーバーライドされた描画コードを使用して透明で非対話的な UIView を追加し、ポリゴンを描画するために CGPoints を渡します
  • CLLocationCoordinate2Dポリゴンの座標を取得しCGPoints、描画用に変換します
  • CGPointsマップが移動するたびにそれらを更新して、正しい位置に再描画し、UIViewそれ自体を再描画できるようにします。

したがって、あなたがしたいことは、オーバーライドされたメソッドUIViewを持つ透過的で非ユーザーインタラクティブなマップビューの上に追加することです。iはそれぞれの閉じた多角形で、drawRectjCGpoint **points,points[i][j]多角形の個々の点です。クラスは次のようになります。OverView と呼びましょう。

#import "OverView.h"

@interface OverView ()
{
    CGPoint **points;
    int *pointsForPolygon;
    int count;
}

@end

@implementation OverView

- (id)initWithFrame:(CGRect)frame andNumberOfPoints:(int)numpoints andPoints:(CGPoint **)passedPoints andPointsForPolygon:(int *)passedPointsForPolygon;{
    self = [super initWithFrame:frame];
    if (self) {

        // You want this to be transparent and non-user-interactive

        self.userInteractionEnabled = NO;
        self.backgroundColor = [UIColor clearColor];

        // Passed data

        points = passedPoints; // all CGPoints
        pointsForPolygon = passedPointsForPolygon; // number of cgpoints for each polygon
        count = numpoints; // Number of polygons
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect
{

    for(int i=0; i<count; i++) // For each of polygons, like blue ones in picture above
    {
        if (pointsForPolygon[i] < 2) // Require at least 3 points
            continue;

        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);

        CGContextSetLineWidth(context, 2.0);

        for(int j = 0; j < pointsForPolygon[i]; j++)
        {
            CGPoint point = points[i][j];

            if(j == 0)
            {
                // Move to the first point
                CGContextMoveToPoint(context, point.x, point.y);
            }
            else
            {
                // Line to others
                CGContextAddLineToPoint(context, point.x, point.y);
            }
        }

        CGContextClosePath(context); // And close the path
        CGContextFillPath(context);
        CGContextStrokePath(context);
    }
}


@end

さて、元UIViewControllerのmapviewでは、すべてのポリゴンを構成するすべての座標にアクセスする必要があります(ポイントと同じ配列ですがCLLocationCoordinate2D、 、およびその他のいくつかで構成されています:

@interface ViewController () <GMSMapViewDelegate>
{
    CGPoint **points;
    int howmanypoints;
    int *pointsForPolygon;
    CLLocationCoordinate2D **acoordinates;
}

acoordinatesポリゴンの座標を取得するたびに入力されます。パーサー メソッドの一部である Fusion Tables からの応答文字列を解析します

- (void)parseResponse2
{
    NSMutableArray *fullArray = [[self.fusionStringBeaches componentsSeparatedByString:@"\n"] mutableCopy];

    howmanypoints = fullArray.count; // This is number of polygons

    pointsForPolygon = (int *)calloc(howmanypoints, sizeof(int)); // Number of points for each of the polygons
    points = (CGPoint **)calloc(howmanypoints, sizeof(CGPoint *));
    acoordinates = (CLLocationCoordinate2D **)calloc(howmanypoints, sizeof(CLLocationCoordinate2D *));

    for(int i=0; i<fullArray.count; i++)
    {

        // Some parsing skipped here

        points[i] = (CGPoint *)calloc(koji, sizeof(CGPoint));
        acoordinates[i] = (CLLocationCoordinate2D *)calloc(koji, sizeof(CLLocationCoordinate2D));
        pointsForPolygon[i] = koji;

        if (koji > 2)
        {
            // Parsing skipped                
            for (int j=0; j<koji; j++)
            {
                CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(coordinates[j].latitude, coordinates[j].longitude);

                // Here, you convert coordinate and add it to points array to be passed to overview
                points[i][j] = [self.mapView.projection pointForCoordinate:coordinate];
                // and added that coordinate to array for future access
                acoordinates[i][j] = coordinate;
            }
        }
    }

    // Finally, allocate OverView passing points array and polygon and coordinate counts
    self.overView = [[OverView alloc] initWithFrame:self.view.bounds
                                  andNumberOfPoints:howmanypoints
                                          andPoints:points
                                andPointsForPolygon:pointsForPolygon];

     // And add it to view
    [self.view addSubview:self.overView];

}

- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)positionこれで、必要な場所にポリゴンができましたが、描画されたポリゴンはマップと共に移動しないため、デリゲート メソッドを観察する必要があります。トリックは、座標の 2D 配列があり、次のようにacoordinatesヘルパー関数(CGPoint *)[self.mapview.projection pointForCoordinate:(CLLocationCoordinate2D)coordinate]を使用して位置を再計算できることです。

- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position
{    
    if (points != nil)
    {
        // Determine new points to pass
        for (int i=0; i<howmanypoints; i++)
        {
            for(int j=0; j<pointsForPolygon[i]; j++)
            {
                // Call method to determine new CGPoint for each coordinate
                points[i][j] = [self.mapView.projection pointForCoordinate:acoordinates[i][j]];
            }
        }

        // No need to pass points again as they were passed as pointers, just refresh te view    
        [self.overView setNeedsDisplay];
    }

}

以上です。要点を理解していただければ幸いです。何かを明確にする必要がある場合は、コメントしてください。小さな完全なプロジェクトを作成し、それを github にアップロードして、よりよく調査できるようにすることもできます。

于 2013-03-08T19:54:38.443 に答える
2

ポリラインはポリゴンとは異なります。ポリラインには、塗りつぶしの色の概念がありません。ポリゴンを SDK に追加するための機能リクエストを提出します。

于 2013-03-05T23:34:59.197 に答える