Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions ShapeReducer/ShapeReducer.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
#import <Foundation/Foundation.h>

@interface ShapePoint : NSObject {
double latitude;
double longitude;
unsigned int sequence;
}

@property (nonatomic, assign) double latitude;
@property (nonatomic, assign) double longitude;
@property unsigned int sequence;
@property (nonatomic, readonly) double latitude;
@property (nonatomic, readonly) double longitude;

- (id)initWithLatitude:(double)aLatitude longitude:(double)aLongitude sequence:(unsigned int)aSequence;
- (id)initWithLatitude:(double)aLatitude longitude:(double)aLongitude;

@end

@interface Shape : NSObject {
@private
NSMutableArray *_points;
BOOL _needs_sort;
}

@property (nonatomic, retain) NSMutableArray *_points;
@property BOOL _needs_sort;
@property (nonatomic, strong) NSMutableArray *_points;

- (void)addPoint:(ShapePoint *)point;
- (NSArray *)points;
Expand All @@ -31,6 +25,6 @@
@interface ShapeReducer : NSObject

- (Shape*)reduce:(Shape*)aShape tolerance:(double)tolerance;
- (void) douglasPeuckerReductionWithTolerance:(double)tolerance shape:(Shape*)shape outputShape:(Shape*)outputShape firstIndex:(int)first lastIndex:(int)last;
- (void) douglasPeuckerReductionWithTolerance:(double)tolerance shape:(Shape*)shape outputShape:(Shape*)outputShape firstIndex:(NSUInteger)first lastIndex:(NSUInteger)last;
+ (double)orthogonalDistanceWithPoint:(ShapePoint *)point lineStart:(ShapePoint *)lineStart lineEnd:(ShapePoint *)lineEnd;
@end
69 changes: 17 additions & 52 deletions ShapeReducer/ShapeReducer.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,109 +2,76 @@

@implementation ShapePoint

@synthesize latitude, longitude, sequence;

- (id)initWithLatitude:(double)aLatitude longitude:(double)aLongitude sequence:(unsigned int)aSequence {
- (id)initWithLatitude:(double)aLatitude longitude:(double)aLongitude {
if ((self = [super init])) {
self.latitude = aLatitude;
self.longitude = aLongitude;
self.sequence = aSequence;
}
return self;
}

- (id)init
{
self = [super init];
return self;
_latitude = aLatitude;
_longitude = aLongitude;
}
return self;
}

@end

@implementation Shape

@synthesize _points, _needs_sort;
@synthesize _points;

- (id)init
{
if ((self = [super init])) {
_points = [[NSMutableArray alloc] init];
_needs_sort = NO;
}
}
return self;
}

- (void)addPoint:(ShapePoint *)point {
[_points addObject:point];
_needs_sort = YES;
}

- (NSArray *)points {
if (_needs_sort) {
NSComparisonResult (^sortBlock)(id, id) = ^(id obj1, id obj2) {
if ([obj1 sequence] > [obj2 sequence]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 sequence] < [obj2 sequence]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
};
NSArray *sortedPoints = [_points sortedArrayUsingComparator:sortBlock];
return sortedPoints;
}
return _points;
}

- (void)dealloc {
[_points release];
[super dealloc];
_points = nil;
}

@end


@implementation ShapeReducer

- (id)init
{
self = [super init];

return self;
}

- (Shape*)reduce:(Shape*)aShape tolerance:(double)tolerance {
if (tolerance <= 0 || [aShape.points count] < 3) {
return aShape;
}

NSArray *points = [aShape points];
Shape *newShape = [[[Shape alloc] init] autorelease];
NSArray *points = aShape.points;
Shape *newShape = [[Shape alloc] init];

[newShape addPoint:[points objectAtIndex:0]];
[newShape addPoint:[points lastObject]];
[newShape addPoint:points.firstObject];

[self douglasPeuckerReductionWithTolerance:tolerance shape:aShape
outputShape:newShape firstIndex:0 lastIndex:[points count]-1];

return newShape;
[newShape addPoint:points.lastObject];

return newShape;
}

- (void) douglasPeuckerReductionWithTolerance:(double)tolerance shape:(Shape*)shape outputShape:(Shape*)outputShape firstIndex:(int)first lastIndex:(int)last {
- (void) douglasPeuckerReductionWithTolerance:(double)tolerance shape:(Shape*)shape outputShape:(Shape*)outputShape firstIndex:(NSUInteger)first lastIndex:(NSUInteger)last {
if (last <= first + 1) {
return;
}

NSArray *points = [shape points];

double distance, maxDistance = 0.0;
int indexFarthest = 0;
NSUInteger indexFarthest = 0;

ShapePoint *firstPoint = [points objectAtIndex:first];
ShapePoint *lastPoint = [points objectAtIndex:last];

for (int idx=first+1; idx<last; idx++) {
for (NSUInteger idx=first+1; idx<last; idx++) {
ShapePoint *point = [points objectAtIndex:idx];

distance = [ShapeReducer orthogonalDistanceWithPoint:point lineStart:firstPoint lineEnd:lastPoint];
Expand All @@ -118,11 +85,9 @@ - (void) douglasPeuckerReductionWithTolerance:(double)tolerance shape:(Shape*)sh

if (maxDistance>tolerance && indexFarthest!=0) {
//add index of Point to list of Points to keep
[outputShape addPoint:[points objectAtIndex:indexFarthest]];

[self douglasPeuckerReductionWithTolerance:tolerance shape:shape
outputShape:outputShape firstIndex:first lastIndex:indexFarthest];

[outputShape addPoint:[points objectAtIndex:indexFarthest]];
[self douglasPeuckerReductionWithTolerance:tolerance shape:shape outputShape:outputShape firstIndex:indexFarthest lastIndex:last];
}
}
Expand Down