diff --git a/Demo App/Classes/ShapeKitViewController.m b/Demo App/Classes/ShapeKitViewController.m index e63eef1..d8a2b35 100644 --- a/Demo App/Classes/ShapeKitViewController.m +++ b/Demo App/Classes/ShapeKitViewController.m @@ -30,7 +30,16 @@ - (void)loadView { } */ - +- (ShapeKitPolygon *)loadWKBPolygonFromFile:(NSString *)file { + ShapeKitPolygon * poly = nil; + NSString *path = [[NSBundle mainBundle] pathForResource:file ofType:@"plist"]; + NSDictionary *stupidDict = [NSDictionary dictionaryWithContentsOfFile:path]; + NSData *geomData = [stupidDict objectForKey:@"shape"]; + if (geomData && [geomData length]) { + poly = [[[ShapeKitPolygon alloc] initWithWKB:[geomData bytes] size:[geomData length]] autorelease]; + } + return poly; +} // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { @@ -134,13 +143,19 @@ - (void)viewDidLoad { [theMap addOverlay:[line convexHull].geometry]; [theMap addAnnotation:[line pointOnSurface].geometry]; [theMap addAnnotation:[line centroid].geometry]; - - - [myPoint release]; [polygon release]; [line release]; + + polygon = [self loadWKBPolygonFromFile:@"PlanID20-82"]; + polygon.geometry.title = @"82"; + [theMap addOverlay:polygon.geometry]; + + polygon = [self loadWKBPolygonFromFile:@"PlanID20-83"]; + polygon.geometry.title = @"83"; + [theMap addOverlay:polygon.geometry]; + } diff --git a/Demo App/PlanID20-82.plist b/Demo App/PlanID20-82.plist new file mode 100644 index 0000000..4dae31a Binary files /dev/null and b/Demo App/PlanID20-82.plist differ diff --git a/Demo App/PlanID20-83.plist b/Demo App/PlanID20-83.plist new file mode 100644 index 0000000..8d99a3c Binary files /dev/null and b/Demo App/PlanID20-83.plist differ diff --git a/Demo App/PlanID20-84.plist b/Demo App/PlanID20-84.plist new file mode 100644 index 0000000..f3f280b Binary files /dev/null and b/Demo App/PlanID20-84.plist differ diff --git a/Demo App/ShapeKit.xcodeproj/project.pbxproj b/Demo App/ShapeKit.xcodeproj/project.pbxproj index 57b7d3b..ce8459f 100755 --- a/Demo App/ShapeKit.xcodeproj/project.pbxproj +++ b/Demo App/ShapeKit.xcodeproj/project.pbxproj @@ -15,6 +15,9 @@ 2899E5220DE3E06400AC0155 /* ShapeKitViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E5210DE3E06400AC0155 /* ShapeKitViewController.xib */; }; 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 28D7ACF80DDB3853001CB0EB /* ShapeKitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* ShapeKitViewController.m */; }; + 37294FD213668095006C6558 /* PlanID20-82.plist in Resources */ = {isa = PBXBuildFile; fileRef = 37294FCF13668095006C6558 /* PlanID20-82.plist */; }; + 37294FD313668095006C6558 /* PlanID20-83.plist in Resources */ = {isa = PBXBuildFile; fileRef = 37294FD013668095006C6558 /* PlanID20-83.plist */; }; + 37294FD413668095006C6558 /* PlanID20-84.plist in Resources */ = {isa = PBXBuildFile; fileRef = 37294FD113668095006C6558 /* PlanID20-84.plist */; }; CE1415521321938600FA3325 /* libgeos_c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE14154F1321938600FA3325 /* libgeos_c.a */; }; CE1415531321938600FA3325 /* libgeos.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE1415501321938600FA3325 /* libgeos.a */; }; CE1415541321938600FA3325 /* libproj.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE1415511321938600FA3325 /* libproj.a */; }; @@ -38,6 +41,9 @@ 28D7ACF70DDB3853001CB0EB /* ShapeKitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShapeKitViewController.m; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* ShapeKit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShapeKit_Prefix.pch; sourceTree = ""; }; + 37294FCF13668095006C6558 /* PlanID20-82.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = "PlanID20-82.plist"; sourceTree = ""; }; + 37294FD013668095006C6558 /* PlanID20-83.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = "PlanID20-83.plist"; sourceTree = ""; }; + 37294FD113668095006C6558 /* PlanID20-84.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = "PlanID20-84.plist"; sourceTree = ""; }; 8D1107310486CEB800E47090 /* ShapeKit-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ShapeKit-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; CE14154F1321938600FA3325 /* libgeos_c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgeos_c.a; path = ../ShapeKit/libs/libgeos_c.a; sourceTree = ""; }; CE1415501321938600FA3325 /* libgeos.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgeos.a; path = ../ShapeKit/libs/libgeos.a; sourceTree = ""; }; @@ -122,6 +128,9 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 37294FCF13668095006C6558 /* PlanID20-82.plist */, + 37294FD013668095006C6558 /* PlanID20-83.plist */, + 37294FD113668095006C6558 /* PlanID20-84.plist */, 2899E5210DE3E06400AC0155 /* ShapeKitViewController.xib */, 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* ShapeKit-Info.plist */, @@ -195,6 +204,9 @@ files = ( 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 2899E5220DE3E06400AC0155 /* ShapeKitViewController.xib in Resources */, + 37294FD213668095006C6558 /* PlanID20-82.plist in Resources */, + 37294FD313668095006C6558 /* PlanID20-83.plist in Resources */, + 37294FD413668095006C6558 /* PlanID20-84.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ShapeKit/ShapeKitGeometry.h b/ShapeKit/ShapeKitGeometry.h index c9e2de2..67b1b87 100644 --- a/ShapeKit/ShapeKitGeometry.h +++ b/ShapeKit/ShapeKitGeometry.h @@ -14,7 +14,67 @@ #import #import #import +/* +// Basic Type definitions +// byte : 1 byte +// uint32 : 32 bit unsigned integer (4 bytes) +// double : double precision number (8 bytes) +// Building Blocks : Point, LinearRing + + typedef struct LinearRing { + unsigned int numPoints; + CLLocationCoordinate2D points[1]; + } LinearRing; + + enum wkbGeometryType { + wkbPoint = 1, + wkbLineString = 2, + wkbPolygon = 3, + wkbMultiPoint = 4, + wkbMultiLineString = 5, + wkbMultiPolygon = 6 + }; + + enum wkbByteOrder { + wkbXDR = 0, // Big Endian + wkbNDR = 1 // Little Endian + }; + + typedef struct WKBPoint { + unsigned char byteOrder; + unsigned int wkbType; // 1=wkbPoint + CLLocationCoordinate2D point; + } WKBPoint; + + typedef struct WKBLineString { + unsigned char byteOrder; + unsigned int wkbType; // 2=wkbLineString + unsigned int numPoints; + CLLocationCoordinate2D points[1]; + } WKBLineString; + + typedef struct WKBPolygon { + unsigned char byteOrder; + unsigned int wkbType; // 3=wkbPolygon + unsigned int numRings; + LinearRing rings[1]; + } WKBPolygon ; + + typedef struct WKBMultiPoint { + unsigned char byteOrder; + unsigned int wkbType; // 4=wkbMultipoint + unsigned int num_wkbPoints; + WKBPoint WKBPoints[1]; + } WKBMultiPoint; + + typedef struct WKBMultiLineString { + unsigned char byteOrder; + unsigned int wkbType; // 5=wkbMultiLineString + unsigned int num_wkbLineStrings; + WKBLineString WKBLineStrings[1]; + } WKBMultiLineString; + */ @interface ShapeKitGeometry : NSObject { NSString *wktGeom; @@ -31,6 +91,7 @@ @property (nonatomic) GEOSGeometry *geosGeom; @property (nonatomic) unsigned int numberOfCoords; +-(id)initWithWKB:(const unsigned char *) wkb size:(size_t)wkb_size; -(id)initWithWKT:(NSString *) wkt; -(id)initWithGeosGeometry:(GEOSGeometry *)geom; -(void) reprojectTo:(NSString *)newProjectionDefinition; diff --git a/ShapeKit/ShapeKitGeometry.mm b/ShapeKit/ShapeKitGeometry.mm index 74d91d0..fa28ea5 100644 --- a/ShapeKit/ShapeKitGeometry.mm +++ b/ShapeKit/ShapeKitGeometry.mm @@ -13,7 +13,6 @@ #import "ShapeKitGeometry.h" #import - @implementation ShapeKitGeometry @synthesize wktGeom,geomType, projDefinition ,geosGeom, numberOfCoords; @@ -28,6 +27,23 @@ - (id) init return self; } +-(id)initWithWKB:(const unsigned char *) wkb size:(size_t)wkb_size { + [self init]; + + GEOSWKBReader *WKBReader = GEOSWKBReader_create_r(handle); + self.geosGeom = GEOSWKBReader_read_r(handle, WKBReader, wkb, wkb_size); + GEOSWKBReader_destroy_r(handle, WKBReader); + + self.geomType = [NSString stringWithUTF8String:GEOSGeomType_r(handle, geosGeom)]; + + GEOSWKTWriter *WKTWriter = GEOSWKTWriter_create_r(handle); + self.wktGeom = [NSString stringWithUTF8String:GEOSWKTWriter_write_r(handle, WKTWriter,geosGeom)]; + GEOSWKTWriter_destroy_r(handle, WKTWriter); + + return self; +} + + -(id)initWithWKT:(NSString *) wkt { [self init]; @@ -45,7 +61,6 @@ -(id)initWithWKT:(NSString *) wkt { return self; } - -(id)initWithGeosGeometry:(GEOSGeometry *)geom { [self init]; geosGeom = geom; @@ -208,6 +223,27 @@ - (void) dealloc @implementation ShapeKitPolyline @synthesize geometry;//,numberOfCoords; +-(id)initWithWKB:(const unsigned char *) wkb size:(size_t)wkb_size{ + [super initWithWKB:wkb size:wkb_size]; + GEOSCoordSequence *sequence = GEOSCoordSeq_clone_r(handle, GEOSGeom_getCoordSeq_r(handle, geosGeom)); + GEOSCoordSeq_getSize_r(handle, sequence, &numberOfCoords); + CLLocationCoordinate2D coords[numberOfCoords]; + + for (int coord = 0; coord < numberOfCoords; coord++) { + double xCoord = NULL; + GEOSCoordSeq_getX_r(handle, sequence, coord, &xCoord); + + double yCoord = NULL; + GEOSCoordSeq_getY_r(handle, sequence, coord, &yCoord); + coords[coord] = CLLocationCoordinate2DMake(yCoord, xCoord); + } + geometry = [MKPolyline polylineWithCoordinates:coords count:numberOfCoords]; + + GEOSCoordSeq_destroy_r(handle, sequence); + + return self; +} + -(id)initWithWKT:(NSString *) wkt { [super initWithWKT:wkt]; GEOSCoordSequence *sequence = GEOSCoordSeq_clone_r(handle, GEOSGeom_getCoordSeq_r(handle, geosGeom)); @@ -285,6 +321,56 @@ - (void) dealloc @implementation ShapeKitPolygon @synthesize geometry;//,numberOfCoords; +-(id)initWithWKB:(const unsigned char *) wkb size:(size_t)wkb_size{ + size_t length = wkb_size; + + [super initWithWKB:wkb size:length]; + GEOSCoordSequence *sequence = nil; + + int numInteriorRings = GEOSGetNumInteriorRings_r(handle, geosGeom); + NSMutableArray *interiors = [[NSMutableArray alloc] init]; + int interiorIndex = 0; + for (interiorIndex = 0; interiorIndex< numInteriorRings; interiorIndex++) { + const GEOSGeometry *interior = GEOSGetInteriorRingN_r(handle, geosGeom, interiorIndex); + sequence = GEOSCoordSeq_clone_r(handle, GEOSGeom_getCoordSeq_r(handle, interior)); + unsigned int numCoordsInt = 0; + GEOSCoordSeq_getSize_r(handle, sequence, &numCoordsInt); + CLLocationCoordinate2D coordsInt[numCoordsInt]; + for (int coord = 0; coord < numCoordsInt; coord++) { + double xCoord = NULL; + + GEOSCoordSeq_getX_r(handle, sequence, coord, &xCoord); + + double yCoord = NULL; + GEOSCoordSeq_getY_r(handle, sequence, coord, &yCoord); + coordsInt[coord] = CLLocationCoordinate2DMake(yCoord, xCoord); + } + [interiors addObject:[MKPolygon polygonWithCoordinates:coordsInt count:numCoordsInt]]; + GEOSCoordSeq_destroy_r(handle, sequence); + } + const GEOSGeometry *exterior = GEOSGetExteriorRing_r(handle, geosGeom); + sequence = GEOSCoordSeq_clone_r(handle, GEOSGeom_getCoordSeq_r(handle, exterior)); + GEOSCoordSeq_getSize_r(handle, sequence, &numberOfCoords); + CLLocationCoordinate2D coordsExt[numberOfCoords]; + for (int coord = 0; coord < numberOfCoords; coord++) { + double xCoord = NULL; + GEOSCoordSeq_getX_r(handle, sequence, coord, &xCoord); + + double yCoord = NULL; + GEOSCoordSeq_getY_r(handle, sequence, coord, &yCoord); + coordsExt[coord] = CLLocationCoordinate2DMake(yCoord, xCoord); + } + if ([interiors count]) + geometry = [MKPolygon polygonWithCoordinates:coordsExt count:numberOfCoords interiorPolygons:interiors]; + else + geometry = [MKPolygon polygonWithCoordinates:coordsExt count:numberOfCoords]; + + GEOSCoordSeq_destroy_r(handle, sequence); + [interiors release]; + + return self; +} + -(id)initWithWKT:(NSString *) wkt { [super initWithWKT:wkt]; GEOSCoordSequence *sequence = GEOSCoordSeq_clone_r(handle, GEOSGeom_getCoordSeq_r(handle, GEOSGetExteriorRing(geosGeom)));