Как создать статический, фактический подкласс MKOverlayPathRenderer ширины?
Я работал над простым наложением пути к существующему MKMapView. Он берет CGMutablePath и рисует его на карте. Целью является то, что путь рисуется, представляя фактическую ширину. Например, подкласс принимает ширину в метрах и преобразует эту ширину в репрезентативную ширину линии. Вот одна версия кода, которая вычисляет ширину линии:
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
float mapPoints = meterWidth * MKMapPointsPerMeterAtLatitude(self.averageLatitude);
float screenPoints = mapPoints * zoomScale; // dividing would keep the apparent width constant
self.lineWidth = ceilf(screenPoints * 2);
CGContextAddPath(context, _mutablePath);
[self applyStrokePropertiesToContext:context atZoomScale:zoomScale];
CGContextStrokePath(context);
Здесь мы сначала находим количество точек карты, которые соответствуют нашей ширине линии, а затем конвертируем это в точки экрана. Мы делаем преобразование на основе комментариев заголовка в MKGeometry.h:
// MKZoomScale provides a conversion factor between MKMapPoints and screen points.
// When MKZoomScale = 1, 1 screen point = 1 MKMapPoint. When MKZoomScale is
// 0.5, 1 screen point = 2 MKMapPoints.
Наконец, мы добавляем путь к контексту, применяем к нему свойства обводки и обводим его.
Однако это дает чрезвычайно неудачные результаты. Рендерер часто рисует случайные фрагменты линий в разных местах за пределами ожидаемой области живого изображения или вообще не рисует некоторые плитки. Иногда ЦП привязывается, перерисовывая несколько версий одной и той же плитки (насколько я могу судить) снова и снова. Документы не очень помогают в этом случае.
У меня есть рабочая версия, но она не кажется правильным решением, поскольку она полностью игнорирует zoomScale и не использует -applyStrokePropertiesToContext:atZoomScale:
float mapPoints = meterWidth * MKMapPointsPerMeterAtLatitude(self.averageLatitude);
self.lineWidth = ceilf(mapPoints * 2);
CGContextAddPath(context, _mutablePath);
CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextStrokePath(context);
У кого-нибудь есть указания на то, что не так с этой реализацией?