Я вижу, что протокол GMSPolyline
уже определяет свойство его цвета штриха, но есть ли способ затенять его полигон (в идеале с прозрачностью)? Я ищу эквивалент Google Maps для MKPolygon
и друзей.Нарисуйте GMSPolyline с цветом фона
ответ
Полилиния отличается от полигона. Полилины не имеют понятия цвета заливки. Файл feature request для многоугольников, которые будут добавлены в SDK.
Существует способ, вы можете получить что-то вроде этого:
подхода является довольно прост:
- Добавить прозрачные Невзаимодействующие UIView с перекрываться кода рисования и передать его CGPoints для чертежные полигоны
- Получить координаты
CLLocationCoordinate2D
для полигонов и преобразовать их вCGPoints
для рисования - Обновите эти
CGPoints
каждый раз, когда перемещается карта, чтобы вы могли перерисовать их в нужном положении и сделать так, чтобыUIView
перерисовать себя.
Итак, что вы хотите сделать, это добавить UIView
на верхней части MapView, который является прозрачным и не userinteractive, который переопределен drawRect
метод. Он снабжен двойным массивом CGPoints, например CGpoint **points,
, с points[i][j]
, где 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, чтобы вы могли исследовать его лучше.
GMSPolyline - это протокол, а не класс! – Felix
Достаточно справедливо .... –
не уверен, что это было в предыдущих версиях SDK, но в 1.2 GMSPolyline явно является классом и протоколом. – myell0w