aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h1
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m298
-rw-r--r--Source/SPGeometryDataView.h16
-rw-r--r--Source/SPGeometryDataView.m114
-rw-r--r--Source/SPTableContent.m10
5 files changed, 435 insertions, 4 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h
index 7d141991..cca59b30 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.h
@@ -58,6 +58,7 @@ typedef struct st_point_2d_
- (NSUInteger)length;
- (NSData*)data;
- (NSString*)wktString;
+- (NSDictionary*)coordinates;
- (NSInteger)wkbType;
- (NSString*)wktType;
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m
index 1c511af3..b46a0dc7 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPGeometryData.m
@@ -352,6 +352,304 @@
}
/**
+ * Return a dictionary of coordinates, bbox, etc. to be able to draw the given geometry.
+ *
+ * @return A dictionary having the following keys: "bbox" as NSArray of NSNumbers of x_min x_max y_min y_max, "coordinates" as NSArray containing the
+ * the to be drawn points as NSPoint strings, "type" as NSString
+ */
+- (NSDictionary*)coordinates
+{
+
+ char byteOrder;
+ UInt32 geoType, numberOfItems, numberOfSubItems, numberOfSubSubItems, numberOfCollectionItems;
+ st_point_2d aPoint;
+
+ NSUInteger i, j, k, n; // Loop counter for numberOf...Items
+ NSUInteger ptr = BUFFER_START; // pointer to geoBuffer while parsing
+
+ double x_min = 1e999;
+ double x_max = -1e999;
+ double y_min = 1e999;
+ double y_max = -1e999;
+
+ NSMutableArray *coordinates = [NSMutableArray array];
+ NSMutableArray *subcoordinates = [NSMutableArray array];
+
+ if (bufferLength < WKB_HEADER_SIZE)
+ return @"Header Error";
+
+ byteOrder = geoBuffer[ptr];
+
+ if(byteOrder != 0x1)
+ return @"Byte order not yet supported";
+
+ ptr++;
+ geoType = geoBuffer[ptr];
+ ptr += SIZEOF_STORED_UINT32;
+
+ switch(geoType) {
+
+ case wkb_point:
+ memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ x_min = aPoint.x;
+ x_max = aPoint.x;
+ y_min = aPoint.y;
+ y_max = aPoint.y;
+ [coordinates addObject:NSStringFromPoint(NSMakePoint(aPoint.x, aPoint.y))];
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSArray arrayWithObjects:
+ [NSNumber numberWithDouble:x_min],
+ [NSNumber numberWithDouble:x_max],
+ [NSNumber numberWithDouble:y_min],
+ [NSNumber numberWithDouble:y_max],
+ nil], @"bbox",
+ coordinates, @"coordinates",
+ @"POINT", @"type",
+ nil];
+ break;
+
+ case wkb_linestring:
+ numberOfItems = geoBuffer[ptr];
+ ptr += SIZEOF_STORED_UINT32;
+ for(i=0; i < numberOfItems; i++) {
+ memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ x_min = (aPoint.x < x_min) ? aPoint.x : x_min;
+ x_max = (aPoint.x > x_max) ? aPoint.x : x_max;
+ y_min = (aPoint.y < y_min) ? aPoint.y : y_min;
+ y_max = (aPoint.y > y_max) ? aPoint.y : y_max;
+ [coordinates addObject:NSStringFromPoint(NSMakePoint(aPoint.x, aPoint.y))];
+ ptr += POINT_DATA_SIZE;
+ }
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSArray arrayWithObjects:
+ [NSNumber numberWithDouble:x_min],
+ [NSNumber numberWithDouble:x_max],
+ [NSNumber numberWithDouble:y_min],
+ [NSNumber numberWithDouble:y_max],
+ nil], @"bbox",
+ coordinates, @"coordinates",
+ @"LINESTRING", @"type",
+ nil];
+ break;
+
+ case wkb_polygon:
+ numberOfItems = geoBuffer[ptr];
+ ptr += SIZEOF_STORED_UINT32;
+ for(i=0; i < numberOfItems; i++) {
+ numberOfSubItems = geoBuffer[ptr];
+ ptr += SIZEOF_STORED_UINT32;
+ for(j=0; j < numberOfSubItems; j++) {
+ memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ x_min = (aPoint.x < x_min) ? aPoint.x : x_min;
+ x_max = (aPoint.x > x_max) ? aPoint.x : x_max;
+ y_min = (aPoint.y < y_min) ? aPoint.y : y_min;
+ y_max = (aPoint.y > y_max) ? aPoint.y : y_max;
+ [subcoordinates addObject:NSStringFromPoint(NSMakePoint(aPoint.x, aPoint.y))];
+ ptr += POINT_DATA_SIZE;
+ }
+ [coordinates addObject:[[subcoordinates copy] autorelease]];
+ [subcoordinates removeAllObjects];
+ }
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSArray arrayWithObjects:
+ [NSNumber numberWithDouble:x_min],
+ [NSNumber numberWithDouble:x_max],
+ [NSNumber numberWithDouble:y_min],
+ [NSNumber numberWithDouble:y_max],
+ nil], @"bbox",
+ coordinates, @"coordinates",
+ @"POLYGON", @"type",
+ nil];
+ break;
+
+ // case wkb_multipoint:
+ // [wkt setString:@"MULTIPOINT("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (i < numberOfItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE+WKB_HEADER_SIZE;
+ // }
+ // [wkt appendString:@")"];
+ // return wkt;
+ // break;
+ //
+ // case wkb_multilinestring:
+ // [wkt setString:@"MULTILINESTRING("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // numberOfSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(j=0; j < numberOfSubItems; j++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (j < numberOfSubItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // ptr += WKB_HEADER_SIZE;
+ // [wkt appendFormat:@")%@", (i < numberOfItems-1) ? @"," : @""];
+ // }
+ // [wkt appendString:@")"];
+ // return wkt;
+ // break;
+ //
+ // case wkb_multipolygon:
+ // [wkt setString:@"MULTIPOLYGON("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // numberOfSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(j=0; j < numberOfSubItems; j++) {
+ // numberOfSubSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(k=0; k < numberOfSubSubItems; k++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (k < numberOfSubSubItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // [wkt appendFormat:@")%@", (j < numberOfSubItems-1) ? @"," : @""];
+ // }
+ // ptr += WKB_HEADER_SIZE;
+ // [wkt appendFormat:@")%@", (i < numberOfItems-1) ? @"," : @""];
+ // }
+ // [wkt appendString:@")"];
+ // return wkt;
+ // break;
+ //
+ // case wkb_geometrycollection:
+ // [wkt setString:@"GEOMETRYCOLLECTION("];
+ // numberOfCollectionItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ //
+ // for(n=0; n < numberOfCollectionItems; n++) {
+ //
+ // byteOrder = geoBuffer[ptr];
+ //
+ // if(byteOrder != 0x1)
+ // return @"Byte order not yet supported";
+ //
+ // ptr++;
+ // geoType = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ //
+ // switch(geoType) {
+ //
+ // case wkb_point:
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"POINT(%.16g %.16g)", aPoint.x, aPoint.y];
+ // ptr += POINT_DATA_SIZE;
+ // break;
+ //
+ // case wkb_linestring:
+ // [wkt appendString:@"LINESTRING("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // for(i=0; i < numberOfItems; i++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (i < numberOfItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // [wkt appendString:@")"];
+ // break;
+ //
+ // case wkb_polygon:
+ // [wkt appendString:@"POLYGON("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // for(i=0; i < numberOfItems; i++) {
+ // numberOfSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(j=0; j < numberOfSubItems; j++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (j < numberOfSubItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // [wkt appendFormat:@")%@", (i < numberOfItems-1) ? @"," : @""];
+ // }
+ // [wkt appendString:@")"];
+ // break;
+ //
+ // case wkb_multipoint:
+ // [wkt appendString:@"MULTIPOINT("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (i < numberOfItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE+WKB_HEADER_SIZE;
+ // }
+ // ptr -= WKB_HEADER_SIZE;
+ // [wkt appendString:@")"];
+ // break;
+ //
+ // case wkb_multilinestring:
+ // [wkt appendString:@"MULTILINESTRING("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // numberOfSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(j=0; j < numberOfSubItems; j++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (j < numberOfSubItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // ptr += WKB_HEADER_SIZE;
+ // [wkt appendFormat:@")%@", (i < numberOfItems-1) ? @"," : @""];
+ // }
+ // ptr -= WKB_HEADER_SIZE;
+ // [wkt appendString:@")"];
+ // break;
+ //
+ // case wkb_multipolygon:
+ // [wkt appendString:@"MULTIPOLYGON("];
+ // numberOfItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32+WKB_HEADER_SIZE;
+ // for(i=0; i < numberOfItems; i++) {
+ // numberOfSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(j=0; j < numberOfSubItems; j++) {
+ // numberOfSubSubItems = geoBuffer[ptr];
+ // ptr += SIZEOF_STORED_UINT32;
+ // [wkt appendString:@"("];
+ // for(k=0; k < numberOfSubSubItems; k++) {
+ // memcpy(&aPoint, &geoBuffer[ptr], POINT_DATA_SIZE);
+ // [wkt appendFormat:@"%.16g %.16g%@", aPoint.x, aPoint.y, (k < numberOfSubSubItems-1) ? @"," : @""];
+ // ptr += POINT_DATA_SIZE;
+ // }
+ // [wkt appendFormat:@")%@", (j < numberOfSubItems-1) ? @"," : @""];
+ // }
+ // ptr += WKB_HEADER_SIZE;
+ // [wkt appendFormat:@")%@", (i < numberOfItems-1) ? @"," : @""];
+ // }
+ // ptr -= WKB_HEADER_SIZE;
+ // [wkt appendString:@")"];
+ // break;
+ //
+ // default:
+ // return @"Error geometrycollection type parsing";
+ // }
+ // [wkt appendString:(n < numberOfCollectionItems-1) ? @"," : @""];
+ // }
+ // [wkt appendString:@")"];
+ // return wkt;
+ break;
+
+ default:
+ return nil;
+ }
+ return nil;
+}
+
+/**
* Return the WKB type of the geoBuffer ie if buffer represents a POINT, LINESTRING, etc.
* according to stored wkbType in header file. It returns -1 if an error occurred.
*/
diff --git a/Source/SPGeometryDataView.h b/Source/SPGeometryDataView.h
index a2a620bb..3ff72110 100644
--- a/Source/SPGeometryDataView.h
+++ b/Source/SPGeometryDataView.h
@@ -27,7 +27,21 @@
@interface SPGeometryDataView : NSView
{
-
+ NSString *type;
+ NSArray *coordinates;
+ double x_min;
+ double x_max;
+ double y_min;
+ double y_max;
+ double width;
+ double height;
+ double zoom_factor;
+ double margin_offset;
}
+- (id)initWithCoordinates:(NSDictionary*)coord;
+- (void)setMax:(NSArray*)bbox;
+- (NSPoint)normalizePoint:(NSPoint)aPoint;
+- (NSImage*)image;
+
@end
diff --git a/Source/SPGeometryDataView.m b/Source/SPGeometryDataView.m
index 8cfaf767..45d9632b 100644
--- a/Source/SPGeometryDataView.m
+++ b/Source/SPGeometryDataView.m
@@ -30,15 +30,125 @@
/**
* Initialize SPGeometryDataView object
*/
-- (id)initWithFrame:(NSRect)frame
+- (id)initWithCoordinates:(NSDictionary*)coord
{
- if ( self = [super initWithFrame:frame] )
+
+ margin_offset = 5.0;
+
+ type = [coord objectForKey:@"type"];
+ coordinates = [coord objectForKey:@"coordinates"];
+ x_min = [[[coord objectForKey:@"bbox"] objectAtIndex:0] doubleValue] - margin_offset;
+ x_max = [[[coord objectForKey:@"bbox"] objectAtIndex:1] doubleValue] + margin_offset;
+ y_min = [[[coord objectForKey:@"bbox"] objectAtIndex:2] doubleValue] - margin_offset;
+ y_max = [[[coord objectForKey:@"bbox"] objectAtIndex:3] doubleValue] + margin_offset;
+
+ zoom_factor = 1.0;
+
+ width = x_max - x_min;
+ height = y_max - y_min;
+
+
+ if ( self = [super initWithFrame:NSMakeRect(0,0,width,height)] )
{
;
}
return self;
}
+- (NSPoint)normalizePoint:(NSPoint)aPoint
+{
+ return aPoint;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+
+ if(!type || ![type length] || !coordinates || ![coordinates count]) return;
+
+ NSBezierPath *path, *circlePath;
+ NSColor *polyFillColor = [NSColor colorWithCalibratedRed:.5 green:.5 blue:0.5 alpha:0.05];
+ BOOL isFirst = YES;
+
+ NSPoint aPoint;
+
+ path = [NSBezierPath bezierPathWithRect:[self bounds]];
+ [path setLineWidth:0.1];
+ [[NSColor whiteColor] set];
+ [path fill];
+ [[NSColor grayColor] set];
+ [path stroke];
+
+ path = [NSBezierPath bezierPath];
+ [[NSColor blackColor] set];
+ [path setLineWidth:1];
+
+ if ([type isEqualToString:@"POINT"]) {
+ circlePath = [NSBezierPath bezierPath];
+ [circlePath appendBezierPathWithOvalInRect:NSMakeRect(width/2-2,height/2-2,4,4)];
+ [[NSColor grayColor] setStroke];
+ [[NSColor redColor] setFill];
+ [circlePath stroke];
+ [circlePath fill];
+ }
+ else if([type isEqualToString:@"LINESTRING"]) {
+
+ for(NSString* coord in coordinates) {
+ aPoint = [self normalizePoint:NSPointFromString(coord)];
+ if(isFirst) {
+ [path moveToPoint:aPoint];
+ isFirst = NO;
+ } else {
+ [path lineToPoint:aPoint];
+ }
+ circlePath = [NSBezierPath bezierPath];
+ [circlePath appendBezierPathWithOvalInRect:NSMakeRect(aPoint.x-2,aPoint.y-2,4,4)];
+ [[NSColor grayColor] setStroke];
+ [[NSColor redColor] setFill];
+ [circlePath stroke];
+ [circlePath fill];
+ }
+ [[NSColor blackColor] setStroke];
+ [path stroke];
+
+ }
+ else if([type isEqualToString:@"POLYGON"]) {
+ for(NSArray* polygon in coordinates) {
+ isFirst = YES;
+ for(NSString* coord in polygon) {
+ aPoint = [self normalizePoint:NSPointFromString(coord)];
+ if(isFirst) {
+ [path moveToPoint:aPoint];
+ isFirst = NO;
+ } else {
+ [path lineToPoint:aPoint];
+ }
+ circlePath = [NSBezierPath bezierPath];
+ [circlePath appendBezierPathWithOvalInRect:NSMakeRect(aPoint.x-2,aPoint.y-2,4,4)];
+ [[NSColor grayColor] setStroke];
+ [[NSColor redColor] setFill];
+ [circlePath stroke];
+ [circlePath fill];
+ }
+ [[NSColor blackColor] setStroke];
+ [polyFillColor setFill];
+ [path fill];
+ [path stroke];
+ }
+
+ }
+}
+
+- (NSImage*)image
+{
+
+ [self drawRect:[self bounds]];
+
+ NSImage *image = [[[NSImage alloc] initWithSize:[self bounds].size] autorelease];
+ NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:[self bounds]] autorelease];
+ [image addRepresentation:bitmap];
+ return image;
+}
+
/**
* dealloc
*/
diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m
index 50ce0617..3aa154a7 100644
--- a/Source/SPTableContent.m
+++ b/Source/SPTableContent.m
@@ -51,6 +51,7 @@
#import "SPAlertSheets.h"
#import "SPMainThreadTrampoline.h"
#import "SPHistoryController.h"
+#import "SPGeometryDataView.h"
@implementation SPTableContent
@@ -3349,7 +3350,14 @@
}
}
else if ([theValue isKindOfClass:[MCPGeometryData class]]) {
- ; // TODO
+ // SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[theValue coordinates]];
+ // image = [v image];
+ // if(image) {
+ // [SPTooltip showWithObject:image atLocation:pos ofType:@"image"];
+ // [v release];
+ // return nil;
+ // }
+ // [v release];
}
// Show the cell string value as tooltip (including line breaks and tabs)