summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLPolyline.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src/MGLPolyline.mm')
-rw-r--r--platform/darwin/src/MGLPolyline.mm65
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);
}