简体   繁体   English

用背景色绘制GMSPolyline

[英]Draw a GMSPolyline with a background color

I see that the GMSPolyline protocol already defines a color property for its stroke color, but is there a way to shade the inside of its polygon (ideally with transparency)? 我看到GMSPolyline协议已经为其笔触颜色定义了color属性,但是有没有办法对多边形内部进行着色(理想情况下是透明的)? I'm looking for a Google Maps equivalent to MKPolygon and friends. 我正在寻找与MKPolygon和朋友等效的Google地图。

A Polyline is different to a Polygon's. 折线与折线不同。 Polylines' have no concept of a fill color. 折线没有填充颜色的概念。 File a feature request for Polygons to be added to the SDK. 提出将多边形添加到SDK的功能请求

There is a way, you can get something like this: 有一种方法,您可以获得以下内容:

多边形示例

The approach is rather simple: 方法很简单:

  • Add transparent noninteracting UIView with overriden drawing code and pass it CGPoints for drawing polygons 使用覆盖的绘制代码添加透明的非交互UIView并将其传递给CGPoints以绘制多边形
  • Get your CLLocationCoordinate2D coordinates for polygons and convert them to CGPoints for drawing 获取多边形的CLLocationCoordinate2D坐标并将其转换为CGPoints以进行绘制
  • Update those CGPoints every time map moves so you can redraw them in the right position and make that UIView redraw itself. 每次地图移动时都要更新这些CGPoints以便您可以在正确的位置重绘它们,并使UIView自己重绘。

So, what you want to do is add an UIView on top of your mapview, which is transparent and non-userinteractive, which has overridden drawRect method. 因此,您想要做的是在mapview的顶部添加一个UIView ,它是透明的且非用户交互的,并且已重写了drawRect方法。 It is provided with a double array of CGPoints, like CGpoint **points, acccessed with points[i][j] where i is each of closed polygons and j are individual points of each polygon. 它提供了CGPoints的双重数组,如CGpoint **points,它们都带有points[i][j] ,其中i是每个闭合多边形, j是每个多边形的各个点。 The class would be, let's call it OverView: 该类就是,我们称之为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

Now, in original UIViewController with mapview, you need to have access to all coordinates that make all the polygons (same array as points, but consisting of CLLocationCoordinate2D , and several others: 现在,在带有mapview的原始UIViewController ,您需要访问构成所有多边形的所有坐标(与点相同的数组,但是由CLLocationCoordinate2D以及其他几个CLLocationCoordinate2D组成):

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

acoordinates is populated wherever you get your coordinates for polygons, I parse the response string from Fusion Tables, part of my parser method 无论您在哪里获得多边形的坐标,都会填充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];

}

Now, you have Polygons where you want them, but must observe - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position delegate method as drawn polygons won't move with map. 现在,在需要的位置有多边形,但是必须遵守- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position委托方法,因为绘制的多边形不会随地图一起移动。 The trick is that you have your 2D array of coordinates acoordinates and you can user helper function (CGPoint *)[self.mapview.projection pointForCoordinate:(CLLocationCoordinate2D)coordinate] to recalculate the positions, like: 诀窍在于,你有坐标的二维数组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];
    }

}

And that's it. 就是这样。 Hope you got the gist of it. 希望您能掌握要点。 Please, comment if I need to clarify something. 请发表评论,如果我需要澄清一下。 I can also make a small complete project and upload it to github so you can research it better. 我还可以制作一个完整的小型项目,并将其上传到github,以便您可以更好地进行研究。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM