首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用iOS MySQL MapKit上的iOS WKB几何

使用iOS MySQL MapKit上的iOS WKB几何
EN

Stack Overflow用户
提问于 2011-04-23 06:07:34
回答 2查看 1.1K关注 0票数 0

我知道如何将MySQL几何图形从二进制转换为文本,然后传输/转换它以便在MapKit中使用。然而,这似乎是不必要的低效。我正在寻找一种方法,在考虑带宽效率的情况下,将二进制形状(如多边形)传输到它们的Mapkit相关成员(如MkPolygon)。

有没有一种方法可以直接使用这些二进制图形并在iOS中转换?二进制格式是否足够容易解析?至少在移动设备上之前,我希望避免先转换为文本,然后再转换回二进制,以避免传输数百万个双精度浮点数作为字符串的网络膨胀。

我在GitHub上找到了Michael Weismann's ShapeKit,它获取GEOS几何图形并输出MapKit对象。但是,ShapeKit依赖于WKT作为起点,除非您有一个完全实例化的GEOS对象。因此,我破解了它,从WKB字节构建了GEOS几何图形(通过将MySQL WKB数据填充到NSData中),但从MySQL返回的二进制似乎并不完全是它所期望的。也许有一个端序问题...?

代码语言:javascript
复制
@implementation ShapeKitGeometry
@synthesize wktGeom,geomType, projDefinition ,geosGeom, numberOfCoords;

- (id) init
{
    self = [super init];
    if (self != nil) {
        // initialize GEOS library
        handle = initGEOS_r(notice, log_and_exit);
    }
    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)];
    return self;
}

// .... later in my appDelegate:
- (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;
}

有什么想法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-26 15:06:26

我已经弄明白了。从Michael Weismann的ShapeKit (正如在最初的问题中提到的)开始,我精心设计了一些额外的方法,这些方法将解析WKB二进制多边形(包括任何内部环或“洞”),并输出适合MapKit的适当MKPolygon。

问题解决了……

代码语言:javascript
复制
 /* make sure you grab your Polygon data column from MySQL with the following:
    "select AsBinary(shapeColumn) from tableName;"


  .... add the first three methods found in the question to ShapeGeometry.mm 
    and your application's map view controller (the NSData usage example)

  ALSO, add this method further down in that file, for ShapeKitPolygon
*/

@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;
}
票数 0
EN

Stack Overflow用户

发布于 2011-04-23 06:14:44

您不能使用Can从MySQL服务器中选择多边形,然后在那里进行转换吗?或者这些扩展在iPhone上不可用?

使用:从table_name中选择AsBinary(column_name);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5760553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档