[英]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: 方法很简单:
CLLocationCoordinate2D
coordinates for polygons and convert them to CGPoints
for drawing 获取多边形的CLLocationCoordinate2D
坐标并将其转换为CGPoints
以进行绘制 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.