diff options
Diffstat (limited to 'platform/darwin/src/MGLPolyline.mm')
-rw-r--r-- | platform/darwin/src/MGLPolyline.mm | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index ae4fbe61de..fd75dc2795 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -6,6 +6,7 @@ #import "MGLPolyline+MGLAdditions.h" #import <mbgl/util/geojson.hpp> +#import <mapbox/polylabel.hpp> @implementation MGLPolyline @@ -52,6 +53,61 @@ return self == other || ([other isKindOfClass:[MGLPolyline class]] && [super isEqual:other]); } +- (CLLocationCoordinate2D)coordinate { + NSUInteger count = self.pointCount; + NSAssert(count > 0, @"Polyline must have coordinates"); + + CLLocationCoordinate2D *coordinates = self.coordinates; + CLLocationDistance middle = [self length] / 2.0; + CLLocationDistance traveled = 0.0; + + if (count > 1 || middle > traveled) { + for (NSUInteger i = 0; i < count; i++) { + + MGLRadianCoordinate2D from = MGLRadianCoordinateFromLocationCoordinate(coordinates[i]); + MGLRadianCoordinate2D to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i + 1]); + + if (traveled >= middle) { + double overshoot = middle - traveled; + if (overshoot == 0) { + return coordinates[i]; + } + to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i - 1]); + CLLocationDirection direction = [self direction:from to:to] - 180; + MGLRadianCoordinate2D otherCoordinate = MGLRadianCoordinateAtDistanceFacingDirection(from, + overshoot/mbgl::util::EARTH_RADIUS_M, + MGLRadiansFromDegrees(direction)); + return CLLocationCoordinate2DMake(MGLDegreesFromRadians(otherCoordinate.latitude), + MGLDegreesFromRadians(otherCoordinate.longitude)); + } + + traveled += (MGLDistanceBetweenRadianCoordinates(from, to) * mbgl::util::EARTH_RADIUS_M); + + } + } + + return coordinates[count - 1]; +} + +- (CLLocationDistance)length +{ + CLLocationDistance length = 0.0; + + NSUInteger count = self.pointCount; + CLLocationCoordinate2D *coordinates = self.coordinates; + + for (NSUInteger i = 0; i < count - 1; i++) { + length += (MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinateFromLocationCoordinate(coordinates[i]), MGLRadianCoordinateFromLocationCoordinate(coordinates[i + 1])) * mbgl::util::EARTH_RADIUS_M); + } + + return length; +} + +- (CLLocationDirection)direction:(MGLRadianCoordinate2D)from to:(MGLRadianCoordinate2D)to +{ + return MGLDegreesFromRadians(MGLRadianCoordinatesDirection(from, to)); +} + @end @interface MGLMultiPolyline () @@ -114,6 +170,15 @@ return hash; } +- (CLLocationCoordinate2D)coordinate { + MGLPolyline *polyline = self.polylines.firstObject; + CLLocationCoordinate2D *coordinates = polyline.coordinates; + NSAssert([polyline pointCount] > 0, @"Polyline must have coordinates"); + CLLocationCoordinate2D firstCoordinate = coordinates[0]; + + return firstCoordinate; +} + - (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds { return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds); } |