
Simple & strightforward test of loading shape file and drawing it on MapKit on iOS8 using drawMapRect
GitHub:https://github.com/Sumbera/SHPonMapKit
- draws only polygons so far
- primitive optimization, no scale optimisation
Reading of shape file is performed by shapelib
NS_INLINE NSArray *getPolygonsFromShapeFile(NSString *shpFilePath) {
const char *path = [shpFilePath cStringUsingEncoding:NSUTF8StringEncoding];
SHPHandle shp = SHPOpen(path, "rb");
if (!shp) {
return @[];
}
int numEntities;
int shapeType;
SHPGetInfo(shp, &numEntities, &shapeType, NULL, NULL);
NSMutableArray *allPolygons = [[NSMutableArray alloc] init];
for (int i = 0; i < numEntities; i++) {
@autoreleasepool {
SHPObject *shpObject = SHPReadObject(shp, i);
if (!shpObject) {
continue;
}
if (shpObject->nSHPType == SHPT_POLYGON ||
shpObject->nSHPType == SHPT_POLYGONZ ||
shpObject->nSHPType == SHPT_POLYGONM ||
shpObject->nSHPType == SHPT_MULTIPOLYGON) {
int numParts = shpObject->nParts;
int totalVertexCount = shpObject->nVertices;
for (int n = 0; n < numParts; n++) {
int startVertex = shpObject->panPartStart[n];
int partVertexCount = (n == numParts - 1) ?
totalVertexCount - startVertex :
shpObject->panPartStart[n + 1] - startVertex;
int endIndex = startVertex + partVertexCount;
CLLocationCoordinate2D *coords = malloc(sizeof(CLLocationCoordinate2D) * partVertexCount);
if (!coords) {
continue;
}
for (int pv = startVertex, j = 0; pv < endIndex; pv++, j++) {
coords[j] = CLLocationCoordinate2DMake(shpObject->padfY[pv],
shpObject->padfX[pv]);
}
MKPolygon *singlePolygon = [MKPolygon polygonWithCoordinates:coords
count:partVertexCount];
[allPolygons addObject:singlePolygon];
free(coords);
}
}
SHPDestroyObject(shpObject);
}
}
SHPClose(shp);
return [allPolygons copy];
}
credits/inspiration:
drawing : http://stackoverflow.com/questions/17673410/mkmapview-with-multiple-overlays-memory-issue
parsing : http://www.al-tyus.com/blog/2013/10/14/mapkit-and-esri-shapefiles
shapelib: http://shapelib.maptools.org
dala: http://www.geoportalpraha.cz