diff options
Diffstat (limited to 'Frameworks/MCPKit/MCPFoundationKit')
4 files changed, 145 insertions, 10 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h index 60a7febf..c37e286d 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h @@ -25,15 +25,34 @@ #import <Cocoa/Cocoa.h> #import <Foundation/Foundation.h> +enum wkbType +{ + wkb_point = 1, + wkb_linestring = 2, + wkb_polygon = 3, + wkb_multipoint = 4, + wkb_multilinestring = 5, + wkb_multipolygon = 6, + wkb_geometrycollection = 7 +}; + +typedef struct st_point_2d_ +{ + double x; + double y; +} st_point_2d; + @interface MCPGeometryData : NSObject <NSCoding, NSCopying> { - char *geoBuffer; + Byte *geoBuffer; NSUInteger bufferLength; } -- (id)initWithData:(NSData*)geoData; -+ (id)dataWithData:(NSData*)geoData; +- (id)initWithBytes:(Byte*)geoData length:(NSUInteger)length; ++ (id)dataWithBytes:(Byte*)geoData length:(NSUInteger)length; - (NSString*)description; - (NSUInteger)length; +- (NSData*)data; +- (NSString*)wktString; @end diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m index 9f7ac19a..6a41e657 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m @@ -25,6 +25,11 @@ #import "MCPGeometryData.h" +#define SIZEOF_STORED_UINT32 4 +#define SIZEOF_STORED_DOUBLE 8 +#define POINT_DATA_SIZE (SIZEOF_STORED_DOUBLE*2) +#define WKB_HEADER_SIZE (1+SIZEOF_STORED_UINT32) + @implementation MCPGeometryData - (id)copyWithZone:(NSZone *)zone { return [self retain]; } @@ -38,20 +43,20 @@ return self; } -- (id)initWithData:(NSData*)geoData +- (id)initWithBytes:(Byte*)geoData length:(NSUInteger)length { if ((self = [self init])) { - bufferLength = [geoData length]; + bufferLength = length; geoBuffer = malloc(bufferLength); - memcpy(geoBuffer, [geoData bytes], bufferLength); + memcpy(geoBuffer, geoData, bufferLength); } return self; } -+ (id)dataWithData:(NSData*)geoData ++ (id)dataWithBytes:(Byte*)geoData length:(NSUInteger)length { - return [[[MCPGeometryData alloc] initWithData:geoData] autorelease]; + return [[[MCPGeometryData alloc] initWithBytes:geoData length:length] autorelease]; } - (NSString*)description @@ -64,6 +69,117 @@ return bufferLength; } +- (NSData*)data +{ + return [NSData dataWithBytes:geoBuffer length:bufferLength]; +} + +- (NSString*)wktString +{ + char byteOrder; + UInt32 geoType, c, c1; + st_point_2d aPoint; + NSUInteger ptr; + double x, y; + NSMutableString *wkt = [NSMutableString string]; + NSUInteger i,j; + BOOL raw = NO; + + if (bufferLength < WKB_HEADER_SIZE) + return @"Error"; + + ptr = (raw) ? 0 : 4; + + byteOrder = geoBuffer[ptr]; + + if(byteOrder != 0x1) + return @"Byte order not yet supported"; + + ptr++; + geoType = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32; + + NSData *d; + switch(geoType) { + case wkb_point: + memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE); + return [NSString stringWithFormat:@"POINT(%.16g %.16g)",aPoint.x, aPoint.y]; + break; + case wkb_linestring: + [wkt setString:@"LINESTRING("]; + c = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32; + for(i=0; i<c; i++) { + memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE); + [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (i<c-1) ? @"," : @""]; + ptr += POINT_DATA_SIZE; + } + [wkt appendString:@")"]; + return wkt; + break; + case wkb_polygon: + [wkt setString:@"POLYGON("]; + c = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32; + for(i=0; i<c; i++) { + c1 = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32; + [wkt appendString:@"("]; + for(j=0; j<c1; j++) { + memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE); + [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (j<c1-1) ? @"," : @""]; + ptr += POINT_DATA_SIZE; + } + [wkt appendFormat:@")%@", (i<c-1) ? @"," : @""]; + } + [wkt appendString:@")"]; + return wkt; + break; + case wkb_multipoint: + [wkt setString:@"MULTIPOINT("]; + c = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE; + for(i=0; i<c; i++) { + memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE); + [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (i<c-1) ? @"," : @""]; + ptr += POINT_DATA_SIZE+WKB_HEADER_SIZE; + } + [wkt appendString:@")"]; + return wkt; + break; + case wkb_multilinestring: + [wkt setString:@"MULTILINESTRING("]; + c = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE; + for(i=0; i<c; i++) { + c1 = geoBuffer[ptr]; + ptr += SIZEOF_STORED_UINT32; + [wkt appendString:@"("]; + for(j=0; j<c1; j++) { + memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE); + [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (j<c1-1) ? @"," : @""]; + ptr += POINT_DATA_SIZE; + } + ptr += WKB_HEADER_SIZE; + [wkt appendFormat:@")%@", (i<c-1) ? @"," : @""]; + } + [wkt appendString:@")"]; + return wkt; + break; + case wkb_multipolygon: + // NSLog(@"ml %@", geoData); + + [wkt setString:@"MULTIPOLYGON be patient"]; + break; + case wkb_geometrycollection: + [wkt setString:@"GEOMETRYCOLLECTION be patient"]; + break; + default: + return @"Error geometry type parsing"; + } + return wkt; +} + - (void)dealloc { if(geoBuffer && bufferLength) free(geoBuffer); diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m index 82b0636e..24d14193 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m @@ -470,7 +470,7 @@ const OUR_CHARSET our_charsets60[] = break; case FIELD_TYPE_GEOMETRY: - theCurrentObj = [MCPGeometryData dataWithData:[NSData dataWithBytes:theData length:theLengths[i]]]; + theCurrentObj = [MCPGeometryData dataWithBytes:theData length:theLengths[i]]; break; default: diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m index 7822d896..d26dbafc 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m @@ -322,7 +322,7 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); break; case FIELD_TYPE_GEOMETRY: - cellData = [MCPGeometryData dataWithData:[NSData dataWithBytes:theData length:fieldLengths[i]]]; + cellData = [MCPGeometryData dataWithBytes:theData length:fieldLengths[i]]; break; default: |