diff options
author | Bibiko <bibiko@eva.mpg.de> | 2010-10-07 22:23:29 +0000 |
---|---|---|
committer | Bibiko <bibiko@eva.mpg.de> | 2010-10-07 22:23:29 +0000 |
commit | 933bb6c9254ba4761eb960c1b3893a9e57c39fb6 (patch) | |
tree | bf50da8ca46d1c60b6de5e23e9881b806c75de51 /Frameworks | |
parent | 600314d27c03b299e3a9d0f986698a8c2baca9bc (diff) | |
download | sequelpro-933bb6c9254ba4761eb960c1b3893a9e57c39fb6.tar.gz sequelpro-933bb6c9254ba4761eb960c1b3893a9e57c39fb6.tar.bz2 sequelpro-933bb6c9254ba4761eb960c1b3893a9e57c39fb6.zip |
• enhanced spatial support
- implemented native routine to immediate AsText() [MULTIPOLYGON and GEOMETRYCOLLECTION are not yet ready]
- enabled editing of spatial data in Content View for tables and views and in Custom Query via wkt strings which will be saved automatically as wkb by using GeomFromText()
Diffstat (limited to 'Frameworks')
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: |