Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dloffgren/correctly backed polylines #34

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 36 additions & 36 deletions Source/Framework/Classes/MKGeometry.h
Expand Up @@ -55,30 +55,30 @@ typedef struct {
} MKMapRect;

/*
// 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.
typedef CGFloat MKZoomScale;

// The map point for the coordinate (-90,180)
extern const MKMapSize MKMapSizeWorld;
// The rect that contains every map point in the world.
extern const MKMapRect MKMapRectWorld;

// 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.
typedef CGFloat MKZoomScale;

// The map point for the coordinate (-90,180)
extern const MKMapSize MKMapSizeWorld;
// The rect that contains every map point in the world.
extern const MKMapRect MKMapRectWorld;
*/

// Conversion between unprojected and projected coordinates
extern MKMapPoint MKMapPointForCoordinate(CLLocationCoordinate2D coordinate);
extern CLLocationCoordinate2D MKCoordinateForMapPoint(MKMapPoint mapPoint);

// Conversion between distances and projected coordinates
extern CLLocationDistance MKMetersPerMapPointAtLatitude(CLLocationDegrees latitude);
extern double MKMapPointsPerMeterAtLatitude(CLLocationDegrees latitude);

extern CLLocationDistance MKMetersBetweenMapPoints(MKMapPoint a, MKMapPoint b);
/*
// Conversion between distances and projected coordinates
extern CLLocationDistance MKMetersPerMapPointAtLatitude(CLLocationDegrees latitude);
extern double MKMapPointsPerMeterAtLatitude(CLLocationDegrees latitude);*/

extern const MKMapRect MKMapRectNull;*/
extern CLLocationDistance MKMetersBetweenMapPoints(MKMapPoint a, MKMapPoint b);
/*extern const MKMapRect MKMapRectNull;*/

// Geometric operations on MKMapPoint/Size/Rect. See CGGeometry.h for
// Geometric operations on MKMapPoint/Size/Rect. See CGGeometry.h for
// information on the CGFloat versions of these functions.
static inline MKMapPoint MKMapPointMake(double x, double y) {
return (MKMapPoint){x, y};
Expand Down Expand Up @@ -145,22 +145,22 @@ static inline NSString *MKStringFromMapRect(MKMapRect rect) {
return [NSString stringWithFormat:@"{%@, %@}", MKStringFromMapPoint(rect.origin), MKStringFromMapSize(rect.size)];
}
/*
extern MKMapRect MKMapRectUnion(MKMapRect rect1, MKMapRect rect2);
extern MKMapRect MKMapRectIntersection(MKMapRect rect1, MKMapRect rect2);
extern MKMapRect MKMapRectInset(MKMapRect rect, double dx, double dy);
extern MKMapRect MKMapRectOffset(MKMapRect rect, double dx, double dy);
extern void MKMapRectDivide(MKMapRect rect, MKMapRect *slice, MKMapRect *remainder, double amount, CGRectEdge edge);

extern BOOL MKMapRectContainsPoint(MKMapRect rect, MKMapPoint point);
extern BOOL MKMapRectContainsRect(MKMapRect rect1, MKMapRect rect2);
extern BOOL MKMapRectIntersectsRect(MKMapRect rect1, MKMapRect rect2);

extern MKCoordinateRegion MKCoordinateRegionForMapRect(MKMapRect rect);

extern BOOL MKMapRectSpans180thMeridian(MKMapRect rect);
// For map rects that span the 180th meridian, this returns the portion of the rect
// that lies outside of the world rect wrapped around to the other side of the
// world. The portion of the rect that lies inside the world rect can be
// determined with MKMapRectIntersection(rect, MKMapRectWorld).
extern MKMapRect MKMapRectRemainder(MKMapRect rect);
*/
extern MKMapRect MKMapRectUnion(MKMapRect rect1, MKMapRect rect2);
extern MKMapRect MKMapRectIntersection(MKMapRect rect1, MKMapRect rect2);
extern MKMapRect MKMapRectInset(MKMapRect rect, double dx, double dy);
extern MKMapRect MKMapRectOffset(MKMapRect rect, double dx, double dy);
extern void MKMapRectDivide(MKMapRect rect, MKMapRect *slice, MKMapRect *remainder, double amount, CGRectEdge edge);
extern BOOL MKMapRectContainsPoint(MKMapRect rect, MKMapPoint point);
extern BOOL MKMapRectContainsRect(MKMapRect rect1, MKMapRect rect2);
extern BOOL MKMapRectIntersectsRect(MKMapRect rect1, MKMapRect rect2);
extern MKCoordinateRegion MKCoordinateRegionForMapRect(MKMapRect rect);
extern BOOL MKMapRectSpans180thMeridian(MKMapRect rect);
// For map rects that span the 180th meridian, this returns the portion of the rect
// that lies outside of the world rect wrapped around to the other side of the
// world. The portion of the rect that lies inside the world rect can be
// determined with MKMapRectIntersection(rect, MKMapRectWorld).
extern MKMapRect MKMapRectRemainder(MKMapRect rect);
*/
38 changes: 38 additions & 0 deletions Source/Framework/Classes/MKGeometry.m
@@ -0,0 +1,38 @@
/*
* MKGeometry.m
* MapKit
*
* Created by Zach Drayer on 3/20/13.
*
*/

#import "MKGeometry.h"

#import <tgmath.h>

#define MKEarthRadius 6396002.3421 // In meters. Approximation of the radius used by Apple. This gets us within 7 decimal points of precision in MKMetersBetweenMapPoints

extern MKMapPoint MKMapPointForCoordinate(CLLocationCoordinate2D coordinate)
{
return MKMapPointMake(coordinate.latitude, coordinate.longitude);
}

extern CLLocationCoordinate2D MKCoordinateForMapPoint(MKMapPoint mapPoint)
{
return CLLocationCoordinate2DMake(mapPoint.x, mapPoint.y);
}

// Haversine formula
extern CLLocationDistance MKMetersBetweenMapPoints(MKMapPoint pointA, MKMapPoint pointB)
{
CLLocationDegrees differenceInLatitude = ((M_PI / 180) * (pointB.x - pointA.x)); // convert values to radians
CLLocationDegrees differenceInLongitude = ((M_PI / 180) * (pointB.y - pointA.x));
CLLocationDegrees firstLatitude = ((M_PI / 180) * pointA.x);
CLLocationDegrees secondLatitude = ((M_PI / 180) * pointB.x);

// a: Square of half the chord length between the points
// c: Angular distance in radians
CGFloat a = sin(differenceInLatitude / 2) * sin(differenceInLatitude / 2) + sin(differenceInLongitude / 2) * sin(differenceInLongitude / 2) * cos(firstLatitude) * cos(secondLatitude);
CGFloat c = 2 * atan2(sqrt(a), sqrt(1 - a));
return MKEarthRadius * c;
}
8 changes: 4 additions & 4 deletions Source/Framework/Classes/MKMultiPoint.h
Expand Up @@ -12,12 +12,12 @@
#import <MapKit/MKTypes.h>

@interface MKMultiPoint : MKShape {
CLLocationCoordinate2D *coordinates;
NSUInteger coordinateCount;
MKMapPoint *points;
NSUInteger pointCount;
}

@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates;
@property (nonatomic, readonly) NSUInteger coordinateCount;
@property (nonatomic, readonly) MKMapPoint *points;
@property (nonatomic, readonly) NSUInteger pointCount;

- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range;

Expand Down
8 changes: 4 additions & 4 deletions Source/Framework/Classes/MKMultiPoint.m
Expand Up @@ -11,15 +11,15 @@

@implementation MKMultiPoint

@synthesize coordinates;
@synthesize coordinateCount;
@synthesize points;
@synthesize pointCount;


- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
{
for (int i = range.location; i < range.location+range.length; i++)
for (int i = range.location; i < MAX(range.location+range.length, pointCount); i++)
{
coords[i] = coordinates[i];
coords[i] = MKCoordinateForMapPoint(points[i]);
}
}

Expand Down
8 changes: 4 additions & 4 deletions Source/Framework/Classes/MKPolygon.m
Expand Up @@ -36,7 +36,7 @@ - (CLLocationCoordinate2D) coordinate

- (void)dealloc
{
free(coordinates);
free(points);
[interiorPolygons release];
[super dealloc];
}
Expand All @@ -47,12 +47,12 @@ - (id)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)cou
{
if (self = [super init])
{
coordinates = malloc(sizeof(CLLocationCoordinate2D) * count);
points = malloc(sizeof(MKMapPoint) * count);
for (int i = 0; i < count; i++)
{
coordinates[i] = coords[i];
points[i] = MKMapPointForCoordinate(coords[i]);
}
coordinateCount = count;
pointCount = count;
}
return self;
}
Expand Down
6 changes: 3 additions & 3 deletions Source/Framework/Classes/MKPolygonView.m
Expand Up @@ -89,12 +89,12 @@ - (void)draw:(WebScriptObject *)overlayScriptObject

- (NSArray *)pathForPolygon:(MKPolygon *)aPolygon webScriptObject:(WebScriptObject *)webScriptObject
{
CLLocationCoordinate2D *coordinates = malloc(sizeof(CLLocationCoordinate2D) * aPolygon.coordinateCount);
NSRange range = NSMakeRange(0, aPolygon.coordinateCount);
CLLocationCoordinate2D *coordinates = malloc(sizeof(CLLocationCoordinate2D) * aPolygon.pointCount);
NSRange range = NSMakeRange(0, aPolygon.pointCount);
[aPolygon getCoordinates:coordinates range:range];
NSMutableArray *newPath = [NSMutableArray array];

for (int i = 0; i< aPolygon.coordinateCount; i++)
for (int i = 0; i< aPolygon.pointCount; i++)
{
CLLocationCoordinate2D coordinate = coordinates[i];
NSString *script = [NSString stringWithFormat:@"new google.maps.LatLng(%f, %f);", coordinate.latitude, coordinate.longitude];
Expand Down
1 change: 1 addition & 0 deletions Source/Framework/Classes/MKPolyline.h
Expand Up @@ -13,6 +13,7 @@
@interface MKPolyline : MKMultiPoint <MKOverlay>

+ (MKPolyline *)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+ (MKPolyline *)polylineWithPoints:(MKMapPoint *)points count:(NSUInteger)count;

@end

27 changes: 23 additions & 4 deletions Source/Framework/Classes/MKPolyline.m
Expand Up @@ -22,14 +22,19 @@ + (MKPolyline *)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(
return [[[MKPolyline alloc] initWithCoordinates:coords count:count] autorelease];
}

+ (MKPolyline *)polylineWithPoints:(MKMapPoint *)points count:(NSUInteger)count
{
return [[[MKPolyline alloc] initWithPoints:points count:count] autorelease];
}

- (CLLocationCoordinate2D) coordinate
{
return [super coordinate];
}

- (void)dealloc
{
free(coordinates);
free(points);
[super dealloc];
}

Expand All @@ -39,12 +44,26 @@ - (id)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)cou
{
if (self = [super init])
{
coordinates = malloc(sizeof(CLLocationCoordinate2D) * count);
points = malloc(sizeof(MKMapPoint) * count);
for (int i = 0; i < count; i++)
{
points[i] = MKMapPointForCoordinate(coords[i]);
}
pointCount = count;
}
return self;
}

- (id)initWithPoints:(MKMapPoint *)coords count:(NSUInteger)count
{
if (self = [super init])
{
points = malloc(sizeof(MKMapPoint) * count);
for (int i = 0; i < count; i++)
{
coordinates[i] = coords[i];
points[i] = coords[i];
}
coordinateCount = count;
pointCount = count;
}
return self;
}
Expand Down
6 changes: 3 additions & 3 deletions Source/Framework/Classes/MKPolylineView.m
Expand Up @@ -50,12 +50,12 @@ - (void)draw:(WebScriptObject *)overlayScriptObject
{
if (!path)
{
CLLocationCoordinate2D *coordinates = malloc(sizeof(CLLocationCoordinate2D) * [self polyline].coordinateCount);
NSRange range = NSMakeRange(0, [self polyline].coordinateCount);
CLLocationCoordinate2D *coordinates = malloc(sizeof(CLLocationCoordinate2D) * [self polyline].pointCount);
NSRange range = NSMakeRange(0, [self polyline].pointCount);
[[self polyline] getCoordinates:coordinates range:range];
NSMutableArray *newPath = [NSMutableArray array];

for (int i = 0; i< [self polyline].coordinateCount; i++)
for (int i = 0; i< [self polyline].pointCount; i++)
{
CLLocationCoordinate2D coordinate = coordinates[i];
NSString *script = [NSString stringWithFormat:@"new google.maps.LatLng(%f, %f);", coordinate.latitude, coordinate.longitude];
Expand Down
8 changes: 8 additions & 0 deletions Source/MapKit.xcodeproj/project.pbxproj
Expand Up @@ -113,6 +113,9 @@
5FE1308715E94B9600265D22 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FE1308615E94B9600265D22 /* CoreFoundation.framework */; };
5FE8314812A60AF600728ECE /* MapKitPluginLibrary.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5FE8314712A60AF600728ECE /* MapKitPluginLibrary.xib */; };
5FE8314C12A60BFF00728ECE /* MKMapViewAttributeInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5FE8314B12A60BFF00728ECE /* MKMapViewAttributeInspector.xib */; };
E60096E51701809F00484C44 /* MKGeometry.m in Sources */ = {isa = PBXBuildFile; fileRef = E60096E41701809F00484C44 /* MKGeometry.m */; };
E60096E6170180EC00484C44 /* MKGeometry.m in Sources */ = {isa = PBXBuildFile; fileRef = E60096E41701809F00484C44 /* MKGeometry.m */; };
E60096E7170180EC00484C44 /* MKGeometry.m in Sources */ = {isa = PBXBuildFile; fileRef = E60096E41701809F00484C44 /* MKGeometry.m */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -269,6 +272,7 @@
5FE8314712A60AF600728ECE /* MapKitPluginLibrary.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapKitPluginLibrary.xib; sourceTree = "<group>"; };
5FE8314B12A60BFF00728ECE /* MKMapViewAttributeInspector.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MKMapViewAttributeInspector.xib; sourceTree = "<group>"; };
D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
E60096E41701809F00484C44 /* MKGeometry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKGeometry.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -375,6 +379,7 @@
5FB7407611F8C81800AB2079 /* MKMapView+WebViewIntegration.m */,
5FBAF7C711F1486D004753A9 /* MKTypes.h */,
5FBAF7C811F1486D004753A9 /* MKGeometry.h */,
E60096E41701809F00484C44 /* MKGeometry.m */,
5FBAF7C911F1486D004753A9 /* MapKit.h */,
5FBAF7CA11F1486D004753A9 /* MKUserLocation.h */,
5FBAF7CB11F1486D004753A9 /* MKUserLocation.m */,
Expand Down Expand Up @@ -810,6 +815,7 @@
files = (
5F6EF15011F13BCB0077E84F /* main.m in Sources */,
5F6EF16B11F13CB70077E84F /* DemoAppApplicationDelegate.m in Sources */,
E60096E51701809F00484C44 /* MKGeometry.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -850,6 +856,7 @@
5F39D6FF12B5AB50001B32CD /* MKWebView.m in Sources */,
5F9CE3DB12D15F98006354EF /* MKGeocoder.m in Sources */,
5F96B22613BAB9F4000A1E4A /* MKMapView+Private.m in Sources */,
E60096E6170180EC00484C44 /* MKGeometry.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -860,6 +867,7 @@
5FB7438411FE705E00AB2079 /* MapKitPlugin.m in Sources */,
5FB7438811FE70AC00AB2079 /* MKMapViewAttributeInspector.m in Sources */,
5F19A03E1208F6DE0083FE72 /* MKMapView+MapKitPlugin.m in Sources */,
E60096E7170180EC00484C44 /* MKGeometry.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down