aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-10-07 22:23:29 +0000
committerBibiko <bibiko@eva.mpg.de>2010-10-07 22:23:29 +0000
commit933bb6c9254ba4761eb960c1b3893a9e57c39fb6 (patch)
treebf50da8ca46d1c60b6de5e23e9881b806c75de51 /Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m
parent600314d27c03b299e3a9d0f986698a8c2baca9bc (diff)
downloadsequelpro-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/MCPKit/MCPFoundationKit/MCPGeometryData.m')
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m126
1 files changed, 121 insertions, 5 deletions
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);