Skip to content

Commit

Permalink
geometry utils: haversine distance, geodesics, envelope and point met…
Browse files Browse the repository at this point in the history
…hods
  • Loading branch information
bosborn committed Mar 26, 2024
1 parent 71502dc commit 27f71c9
Show file tree
Hide file tree
Showing 15 changed files with 1,065 additions and 98 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ Adheres to [Semantic Versioning](http://semver.org/).

## 4.1.4 (TBD)

* TBD
* Geometry Utils for Haversine distance, geodesic midpoints, geodesic paths, and geodesic envelopes
* Envelope left mid, bottom mid, right mid, and top mid methods
* Envelope min/max x/y/z/m double value methods
* Point x/y/z/m double value methods

## [4.1.3](https://github.com/ngageoint/simple-features-ios/releases/tag/4.1.3) (11-08-2023)

Expand Down
84 changes: 84 additions & 0 deletions sf-ios/SFGeometryEnvelope.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,55 +323,111 @@
*/
-(instancetype) initWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelope;

/**
* Get the min x value
*
* @return x coordinate
*/
-(double) minXValue;

/**
* Set the min x value
*
* @param x x coordinate
*/
-(void) setMinXValue: (double) x;

/**
* Get the max x value
*
* @return x coordinate
*/
-(double) maxXValue;

/**
* Set the max x value
*
* @param x x coordinate
*/
-(void) setMaxXValue: (double) x;

/**
* Get the min y value
*
* @return y coordinate
*/
-(double) minYValue;

/**
* Set the min y value
*
* @param y y coordinate
*/
-(void) setMinYValue: (double) y;

/**
* Get the max y value
*
* @return y coordinate
*/
-(double) maxYValue;

/**
* Set the max y value
*
* @param y y coordinate
*/
-(void) setMaxYValue: (double) y;

/**
* Get the min z value
*
* @return z coordinate
*/
-(double) minZValue;

/**
* Set the min z value
*
* @param z z coordinate
*/
-(void) setMinZValue: (double) z;

/**
* Get the max z value
*
* @return z coordinate
*/
-(double) maxZValue;

/**
* Set the max z value
*
* @param z z coordinate
*/
-(void) setMaxZValue: (double) z;

/**
* Get the min m value
*
* @return m coordinate
*/
-(double) minMValue;

/**
* Set the min m value
*
* @param m m coordinate
*/
-(void) setMinMValue: (double) m;

/**
* Get the max m value
*
* @return m coordinate
*/
-(double) maxMValue;

/**
* Set the max m value
*
Expand Down Expand Up @@ -456,6 +512,34 @@
*/
-(SFPoint *) topRight;

/**
* Get the left mid point
*
* @return left mid point
*/
-(SFPoint *) leftMid;

/**
* Get the bottom mid point
*
* @return bottom mid point
*/
-(SFPoint *) bottomMid;

/**
* Get the right mid point
*
* @return right mid point
*/
-(SFPoint *) rightMid;

/**
* Get the top mid point
*
* @return top mid point
*/
-(SFPoint *) topMid;

/**
* Get the left line
*
Expand Down
86 changes: 67 additions & 19 deletions sf-ios/SFGeometryEnvelope.m
Original file line number Diff line number Diff line change
Expand Up @@ -178,34 +178,66 @@ -(instancetype) initWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelop
return self;
}

-(double) minXValue{
return [_minX doubleValue];
}

-(void) setMinXValue: (double) x{
[self setMinX:[[NSDecimalNumber alloc] initWithDouble:x]];
}

-(double) maxXValue{
return [_maxX doubleValue];
}

-(void) setMaxXValue: (double) x{
[self setMaxX:[[NSDecimalNumber alloc] initWithDouble:x]];
}

-(double) minYValue{
return [_minY doubleValue];
}

-(void) setMinYValue: (double) y{
[self setMinY:[[NSDecimalNumber alloc] initWithDouble:y]];
}

-(double) maxYValue{
return [_maxY doubleValue];
}

-(void) setMaxYValue: (double) y{
[self setMaxY:[[NSDecimalNumber alloc] initWithDouble:y]];
}

-(double) minZValue{
return [_minZ doubleValue];
}

-(void) setMinZValue: (double) z{
[self setMinZ:[[NSDecimalNumber alloc] initWithDouble:z]];
}

-(double) maxZValue{
return [_maxZ doubleValue];
}

-(void) setMaxZValue: (double) z{
[self setMaxZ:[[NSDecimalNumber alloc] initWithDouble:z]];
}

-(double) minMValue{
return [_minM doubleValue];
}

-(void) setMinMValue: (double) m{
[self setMinM:[[NSDecimalNumber alloc] initWithDouble:m]];
}

-(double) maxMValue{
return [_maxM doubleValue];
}

-(void) setMaxMValue: (double) m{
[self setMaxM:[[NSDecimalNumber alloc] initWithDouble:m]];
}
Expand All @@ -219,11 +251,11 @@ -(BOOL) isMeasured{
}

-(double) xRange{
return [_maxX doubleValue] - [_minX doubleValue];
return [self maxXValue] - [self minXValue];
}

-(double) yRange{
return [_maxY doubleValue] - [_minY doubleValue];
return [self maxYValue] - [self minYValue];
}

-(NSDecimalNumber *) zRange{
Expand Down Expand Up @@ -262,6 +294,22 @@ -(SFPoint *) topRight{
return [SFPoint pointWithX:_maxX andY:_maxY];
}

-(SFPoint *) leftMid{
return [SFPoint pointWithX:_minX andY:[[NSDecimalNumber alloc] initWithDouble:[self midY]]];
}

-(SFPoint *) bottomMid{
return [SFPoint pointWithX:[[NSDecimalNumber alloc] initWithDouble:[self midX]] andY:_minY];
}

-(SFPoint *) rightMid{
return [SFPoint pointWithX:_maxX andY:[[NSDecimalNumber alloc] initWithDouble:[self midY]]];
}

-(SFPoint *) topMid{
return [SFPoint pointWithX:[[NSDecimalNumber alloc] initWithDouble:[self midX]] andY:_maxY];
}

-(SFLine *) left{
return [SFLine lineWithPoint1:[self topLeft] andPoint2:[self bottomLeft]];
}
Expand All @@ -279,11 +327,11 @@ -(SFLine *) top{
}

-(double) midX{
return ([_minX doubleValue] + [_maxX doubleValue]) / 2.0;
return ([self minXValue] + [self maxXValue]) / 2.0;
}

-(double) midY{
return ([_minY doubleValue] + [_maxY doubleValue]) / 2.0;
return ([self minYValue] + [self maxYValue]) / 2.0;
}

-(SFPoint *) centroid{
Expand All @@ -308,10 +356,10 @@ -(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope{

-(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope withAllowEmpty: (BOOL) allowEmpty{

double minX = MAX([self.minX doubleValue], [envelope.minX doubleValue]);
double maxX = MIN([self.maxX doubleValue], [envelope.maxX doubleValue]);
double minY = MAX([self.minY doubleValue], [envelope.minY doubleValue]);
double maxY = MIN([self.maxY doubleValue], [envelope.maxY doubleValue]);
double minX = MAX([self minXValue], [envelope minXValue]);
double maxX = MIN([self maxXValue], [envelope maxXValue]);
double minY = MAX([self minYValue], [envelope minYValue]);
double maxY = MIN([self maxYValue], [envelope maxYValue]);

SFGeometryEnvelope *overlap = nil;

Expand All @@ -324,10 +372,10 @@ -(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope wit

-(SFGeometryEnvelope *) unionWithEnvelope: (SFGeometryEnvelope *) envelope{

double minX = MIN([self.minX doubleValue], [envelope.minX doubleValue]);
double maxX = MAX([self.maxX doubleValue], [envelope.maxX doubleValue]);
double minY = MIN([self.minY doubleValue], [envelope.minY doubleValue]);
double maxY = MAX([self.maxY doubleValue], [envelope.maxY doubleValue]);
double minX = MIN([self minXValue], [envelope minXValue]);
double maxX = MAX([self maxXValue], [envelope maxXValue]);
double minY = MIN([self minYValue], [envelope minYValue]);
double maxY = MAX([self maxYValue], [envelope maxYValue]);

SFGeometryEnvelope *unionEnvelope = nil;

Expand All @@ -343,27 +391,27 @@ -(BOOL) containsPoint: (SFPoint *) point{
}

-(BOOL) containsPoint: (SFPoint *) point withEpsilon: (double) epsilon{
return [self containsX:[point.x doubleValue] andY:[point.y doubleValue] withEpsilon:epsilon];
return [self containsX:[point xValue] andY:[point yValue] withEpsilon:epsilon];
}

-(BOOL) containsX: (double) x andY: (double) y{
return [self containsX:x andY:y withEpsilon:0.0];
}

-(BOOL) containsX: (double) x andY: (double) y withEpsilon: (double) epsilon{
return x >= [_minX doubleValue] - epsilon && x <= [_maxX doubleValue] + epsilon
&& y >= [_minY doubleValue] - epsilon && y <= [_maxY doubleValue] + epsilon;
return x >= [self minXValue] - epsilon && x <= [self maxXValue] + epsilon
&& y >= [self minYValue] - epsilon && y <= [self maxYValue] + epsilon;
}

-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope{
return [self containsEnvelope:envelope withEpsilon:0.0];
}

-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope withEpsilon: (double) epsilon{
return [_minX doubleValue] - epsilon <= [envelope.minX doubleValue]
&& [_maxX doubleValue] + epsilon >= [envelope.maxX doubleValue]
&& [_minY doubleValue] - epsilon <= [envelope.minY doubleValue]
&& [_maxY doubleValue] + epsilon >= [envelope.maxY doubleValue];
return [self minXValue] - epsilon <= [envelope minXValue]
&& [self maxXValue] + epsilon >= [envelope maxXValue]
&& [self minYValue] - epsilon <= [envelope minYValue]
&& [self maxYValue] + epsilon >= [envelope maxYValue];
}

-(SFGeometry *) buildGeometry{
Expand Down
28 changes: 28 additions & 0 deletions sf-ios/SFPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,27 +292,55 @@
*/
-(instancetype) initWithPoint: (SFPoint *) point;

/**
* Get the x value
*
* @return x coordinate
*/
-(double) xValue;

/**
* Set the x value
*
* @param x x coordinate
*/
-(void) setXValue: (double) x;

/**
* Get the y value
*
* @return y coordinate
*/
-(double) yValue;

/**
* Set the y value
*
* @param y y coordinate
*/
-(void) setYValue: (double) y;

/**
* Get the z value
*
* @return z coordinate
*/
-(double) zValue;

/**
* Set the z value
*
* @param z z coordinate
*/
-(void) setZValue: (double) z;

/**
* Get the m value
*
* @return m coordinate
*/
-(double) mValue;

/**
* Set the m value
*
Expand Down
Loading

0 comments on commit 27f71c9

Please sign in to comment.