2013-03-05 4 views
0

Я вижу, что протокол GMSPolyline уже определяет свойство его цвета штриха, но есть ли способ затенять его полигон (в идеале с прозрачностью)? Я ищу эквивалент Google Maps для MKPolygon и друзей.Нарисуйте GMSPolyline с цветом фона

+0

GMSPolyline - это протокол, а не класс! – Felix

+0

Достаточно справедливо .... –

+0

не уверен, что это было в предыдущих версиях SDK, но в 1.2 GMSPolyline явно является классом и протоколом. – myell0w

ответ

2

Полилиния отличается от полигона. Полилины не имеют понятия цвета заливки. Файл feature request для многоугольников, которые будут добавлены в SDK.

1

Существует способ, вы можете получить что-то вроде этого:

Polygons example

подхода является довольно прост:

  • Добавить прозрачные Невзаимодействующие 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, чтобы вы могли исследовать его лучше.