GeoPackage iOS
GeoPackage iOS 库
GeoPackage 库是在 国家地理空间情报局 (NGA) 联合 BIT Systems 开发的。政府拥有“无限权利”,并通过提供开发者以新的方向进行尝试的机会,来增加政府投资的效益。软件的使用、修改和分发权利在 MIT 许可证 中规定。
拉取请求
如果您想为该项目做出贡献,请创建一个拉取请求。我们将审查拉取请求并讨论更改。此项目的所有拉取请求贡献都将根据MIT许可证发布。
先前根据开源许可证发布并随后由NGA员工修改的软件源代码被视为“联合作品”(见17 USC § 101);它部分受版权保护,部分属于公有领域,作为一个整体,受非政府作者的版权保护,必须根据原始开源许可证的条款发布。
关于
GeoPackage iOS 是一个使用Objective-C编写的GeoPackage库的SDK实现,该库遵循Open Geospatial Consortium(OGC)的GeoPackage规范。它由国家地理空间情报局(NGA)列为OGC GeoPackage实现。

GeoPackage SDK提供管理GeoPackage文件的功能,包括读取、写入、导入、导出、分享和打开支持。打开GeoPackage文件提供对要素和瓦片的读写访问。要素支持包括已知二进制和iOS地图形状转换。瓦片生成支持通过URL或要素进行创建。支持GeoPackage格式、标准瓦片API和要素瓦片生成的瓦片提供者。
入门
重要 - 请确保您的Mac已安装autoconf
、automake
和glibtoolize
工具。这些是构建proj4-ios依赖项所必需的。如果没有它们,pod install
将失败。最简单的方法是使用brew install
安装它们
brew install automake
brew install libtool
通过在Podfile中使用支持选项指定该存储库来包含此存储库。
通过CocoaPods获取
pod 'geopackage-ios', '~> 7.4.3'
通过GitHub通过CocoaPods获取
pod 'geopackage-ios', :git => 'https://github.com/ngageoint/geopackage-ios.git', :branch => 'master'
pod 'geopackage-ios', :git => 'https://github.com/ngageoint/geopackage-ios.git', :tag => '7.4.3'
作为本地项目包含
pod 'geopackage-ios', :path => '../geopackage-ios'
使用方法
查看最新的 Appledoc。
示例应用
以下项目展示了如何在宿主应用中使用 geopackage-ios。
GeoPackage MapCache
GeoPackage MapCache 应用提供了一个如何在独立环境中使用 SDK 的详细示例。
MAGE
移动意识 GEOINT 环境(MAGE) 应用提供了移动态势感知能力。它 使用 SDK 提供GeoPackage功能。
Objective-C 示例
// NSString *geoPackageFile = ...;
// MKMapView *mapView = ...;
// Get a manager
GPKGGeoPackageManager *manager = [GPKGGeoPackageFactory manager];
// Available databases
NSArray *databases = [manager databases];
// Import database
BOOL imported = [manager importGeoPackageFromPath:geoPackageFile];
// Open database
GPKGGeoPackage *geoPackage = [manager open:[databases objectAtIndex:0]];
// GeoPackage Table DAOs
GPKGSpatialReferenceSystemDao *srsDao = [geoPackage spatialReferenceSystemDao];
GPKGContentsDao *contentsDao = [geoPackage contentsDao];
GPKGGeometryColumnsDao *geometryColumnsDao = [geoPackage geometryColumnsDao];
GPKGTileMatrixSetDao *tileMatrixSetDao = [geoPackage tileMatrixSetDao];
GPKGTileMatrixDao *tileMatrixDao = [geoPackage tileMatrixDao];
GPKGSchemaExtension *schemaExtension = [[GPKGSchemaExtension alloc] initWithGeoPackage:geoPackage];
GPKGDataColumnsDao *dataColumnsDao = [schemaExtension dataColumnsDao];
GPKGDataColumnConstraintsDao *dataColumnConstraintsDao = [schemaExtension dataColumnConstraintsDao];
GPKGMetadataExtension *metadataExtension = [[GPKGMetadataExtension alloc] initWithGeoPackage:geoPackage];
GPKGMetadataDao *metadataDao = [metadataExtension metadataDao];
GPKGMetadataReferenceDao *metadataReferenceDao = [metadataExtension metadataReferenceDao];
GPKGExtensionsDao *extensionsDao = [geoPackage extensionsDao];
// Feature and tile tables
NSArray<NSString *> *features = [geoPackage featureTables];
NSArray<NSString *> *tiles = [geoPackage tileTables];
// Query Features
NSString *featureTable = [features objectAtIndex:0];
GPKGFeatureDao *featureDao = [geoPackage featureDaoWithTableName:featureTable];
GPKGMapShapeConverter *converter = [[GPKGMapShapeConverter alloc] initWithProjection:featureDao.projection];
GPKGRowResultSet *featureResults = [featureDao results:[featureDao queryForAll]];
@try {
for(GPKGFeatureRow *featureRow in featureResults){
GPKGGeometryData *geometryData = [featureRow geometry];
if(geometryData != nil && !geometryData.empty){
SFGeometry *geometry = geometryData.geometry;
GPKGMapShape *shape = [converter toShapeWithGeometry:geometry];
GPKGMapShape *mapShape = [GPKGMapShapeConverter addMapShape:shape toMapView:mapView];
// ...
}
}
}@finally {
[featureResults close];
}
// Query Tiles
NSString *tileTable = [tiles objectAtIndex:0];
GPKGTileDao *tileDao = [geoPackage tileDaoWithTableName:tileTable];
GPKGRowResultSet *tileResults = [tileDao results:[tileDao queryForAll]];
@try {
for(GPKGTileRow *tileRow in tileResults){
NSData *tileData = [tileRow tileData];
UIImage *tileImage = [tileRow tileDataImage];
// ...
}
}@finally {
[tileResults close];
}
// Retrieve Tiles by XYZ
NSObject<GPKGTileRetriever> *retriever = [[GPKGGeoPackageTileRetriever alloc] initWithTileDao:tileDao];
GPKGGeoPackageTile *geoPackageTile = [retriever tileWithX:2 andY:2 andZoom:2];
if(geoPackageTile != nil){
NSData *tileData = geoPackageTile.data;
UIImage *tileImage = [GPKGImageConverter toImage:tileData];
// ...
}
// Retrieve Tiles by Bounding Box
GPKGTileCreator *tileCreator = [[GPKGTileCreator alloc] initWithTileDao:tileDao andProjection:[PROJProjectionFactory projectionWithEpsgInt:PROJ_EPSG_WORLD_GEODETIC_SYSTEM]];
GPKGGeoPackageTile *geoPackageTile2 = [tileCreator tileWithBoundingBox:[[GPKGBoundingBox alloc] initWithMinLongitudeDouble:-90.0 andMinLatitudeDouble:0.0 andMaxLongitudeDouble:0.0 andMaxLatitudeDouble:66.513260]];
if(geoPackageTile2 != nil){
NSData *tileData = geoPackageTile2.data;
UIImage *tileImage = [GPKGImageConverter toImage:tileData];
// ...
}
// Tile Overlay (GeoPackage or Standard API)
MKTileOverlay *tileOverlay = [GPKGOverlayFactory tileOverlayWithTileDao:tileDao];
tileOverlay.canReplaceMapContent = false;
[mapView addOverlay:tileOverlay];
GPKGBoundingBox *boundingBox = [GPKGBoundingBox worldWebMercator];
PROJProjection *projection = [PROJProjectionFactory projectionWithEpsgInt:PROJ_EPSG_WEB_MERCATOR];
// Index Features
GPKGFeatureIndexManager *indexer = [[GPKGFeatureIndexManager alloc] initWithGeoPackage:geoPackage andFeatureDao:featureDao];
[indexer setIndexLocation:GPKG_FIT_RTREE];
int indexedCount = [indexer index];
// Query Indexed Features in paginated chunks
GPKGFeatureIndexResults *indexResults = [indexer queryForChunkWithBoundingBox:boundingBox inProjection:projection andLimit:50];
GPKGRowPaginatedResults *paginatedResults = [indexer paginate:indexResults];
for(GPKGFeatureRow *featureRow in paginatedResults){
GPKGGeometryData *geometryData = [featureRow geometry];
if(geometryData != nil && !geometryData.empty){
SFGeometry *geometry = geometryData.geometry;
// ...
}
}
// Feature Tile Overlay (dynamically draw tiles from features)
GPKGFeatureTiles *featureTiles = [[GPKGFeatureTiles alloc] initWithFeatureDao:featureDao];
[featureTiles setMaxFeaturesPerTile:[NSNumber numberWithInt:1000]];
GPKGNumberFeaturesTile *numberFeaturesTile = [[GPKGNumberFeaturesTile alloc] init];
[featureTiles setMaxFeaturesTileDraw:numberFeaturesTile];
[featureTiles setIndexManager:indexer];
GPKGFeatureOverlay *featureOverlay = [[GPKGFeatureOverlay alloc] initWithFeatureTiles:featureTiles];
[featureOverlay setMinZoom:[NSNumber numberWithInt:[featureDao zoomLevel]]];
[mapView addOverlay:featureOverlay];
// URL Tile Generator (generate tiles from a URL)
GPKGTileGenerator *urlTileGenerator = [[GPKGUrlTileGenerator alloc] initWithGeoPackage:geoPackage andTableName:@"url_tile_table" andTileUrl:@"http://url/{z}/{x}/{y}.png" andMinZoom:0 andMaxZoom:0 andBoundingBox:boundingBox andProjection:projection];
int urlTileCount = [urlTileGenerator generateTiles];
// Feature Tile Generator (generate tiles from features)
GPKGTileGenerator *featureTileGenerator = [[GPKGFeatureTileGenerator alloc] initWithGeoPackage:geoPackage andTableName:[NSString stringWithFormat:@"tiles_%@", featureTable] andFeatureTiles:featureTiles andMinZoom:1 andMaxZoom:2 andBoundingBox:boundingBox andProjection:projection];
int featureTileCount = [featureTileGenerator generateTiles];
// Close database when done
[geoPackage close];
// Close manager when done
[manager close];
Swift 示例
要从 Swift 中使用它,请从 Swift 项目的桥接头中导入 geopackage-ios 桥接头
#import "geopackage-ios-Bridging-Header.h"
// let geoPackageFile: String = ...
// let mapView: MKMapView = ...
// Get a manager
let manager: GPKGGeoPackageManager = GPKGGeoPackageFactory.manager()
// Available databases
let databases: NSArray = manager.databases() as NSArray
// Import database
let imported: Bool = manager.importGeoPackage(fromPath: geoPackageFile)
// Open database
let geoPackage: GPKGGeoPackage = manager.open(databases.object(at: 0) as? String)
// GeoPackage Table DAOs
let srsDao: GPKGSpatialReferenceSystemDao = geoPackage.spatialReferenceSystemDao()
let contentsDao: GPKGContentsDao = geoPackage.contentsDao()
let geometryColumnsDao: GPKGGeometryColumnsDao = geoPackage.geometryColumnsDao()
let tileMatrixSetDao: GPKGTileMatrixSetDao = geoPackage.tileMatrixSetDao()
let tileMatrixDao: GPKGTileMatrixDao = geoPackage.tileMatrixDao()
let schemaExtension : GPKGSchemaExtension = GPKGSchemaExtension.init(geoPackage: geoPackage)
let dataColumnsDao: GPKGDataColumnsDao = schemaExtension.dataColumnsDao()
let dataColumnConstraintsDao: GPKGDataColumnConstraintsDao = schemaExtension.dataColumnConstraintsDao()
let metadataExtension : GPKGMetadataExtension = GPKGMetadataExtension.init(geoPackage: geoPackage)
let metadataDao: GPKGMetadataDao = metadataExtension.metadataDao()
let metadataReferenceDao: GPKGMetadataReferenceDao = metadataExtension.metadataReferenceDao()
let extensionsDao: GPKGExtensionsDao = geoPackage.extensionsDao()
// Feature and tile tables
let features: NSArray = geoPackage.featureTables() as NSArray
let tiles: NSArray = geoPackage.tileTables() as NSArray
// Query Features
let featureTable: String = features.object(at: 0) as! String
let featureDao: GPKGFeatureDao = geoPackage.featureDao(withTableName: featureTable)
let converter: GPKGMapShapeConverter = GPKGMapShapeConverter(projection: featureDao.projection)
let featureResults: GPKGResultSet = featureDao.queryForAll()
do{
defer{featureResults.close()}
while(featureResults.moveToNext()){
let featureRow: GPKGFeatureRow = featureDao.featureRow(featureResults)
let geometryData: GPKGGeometryData! = featureRow.geometry()
if(geometryData != nil && !geometryData.empty){
let geometry: SFGeometry = geometryData.geometry
let shape: GPKGMapShape = converter.toShape(with: geometry)
let mapShape = GPKGMapShapeConverter.add(shape, to: mapView)
// ...
}
}
}
// Query Tiles
let tileTable: String = tiles.object(at: 0) as! String
let tileDao: GPKGTileDao = geoPackage.tileDao(withTableName: tileTable)
let tileResults: GPKGResultSet = tileDao.queryForAll()
do{
defer{tileResults.close()}
while(tileResults.moveToNext()){
let tileRow: GPKGTileRow = tileDao.tileRow(tileResults)
let tileData: Data = tileRow.tileData()
let tileImage: UIImage = tileRow.tileDataImage()
// ...
}
}
// Retrieve Tiles by XYZ
let retriever = GPKGGeoPackageTileRetriever()
let geoPackageTile: GPKGGeoPackageTile! = retriever.tileWith(x: 2, andY: 2, andZoom: 2)
if(geoPackageTile != nil){
let tileData: Data = geoPackageTile.data
let tileImage: UIImage = GPKGImageConverter.toImage(tileData)
// ...
}
// Retrieve Tiles by Bounding Box
let tileCreator: GPKGTileCreator = GPKGTileCreator(tileDao: tileDao, andProjection: PROJProjectionFactory.projection(withEpsgInt: PROJ_EPSG_WORLD_GEODETIC_SYSTEM))
let geoPackageTile2: GPKGGeoPackageTile! = tileCreator.tile(with: GPKGBoundingBox(minLongitudeDouble: -90.0, andMinLatitudeDouble: 0.0, andMaxLongitudeDouble: 0.0, andMaxLatitudeDouble: 66.513260))
if(geoPackageTile2 != nil){
let tileData: Data = geoPackageTile2.data
let tileImage: UIImage = GPKGImageConverter.toImage(tileData)
// ...
}
// Tile Overlay (GeoPackage or Standard API)
let tileOverlay: MKTileOverlay = GPKGOverlayFactory.tileOverlay(with: tileDao)
tileOverlay.canReplaceMapContent = false
mapView.addOverlay(tileOverlay)
let boundingBox: GPKGBoundingBox = GPKGBoundingBox.worldWebMercator()
let projection: PROJProjection = PROJProjectionFactory.projection(withEpsgInt: PROJ_EPSG_WEB_MERCATOR)
// Index Features
let indexer: GPKGFeatureIndexManager = GPKGFeatureIndexManager(geoPackage: geoPackage, andFeatureDao: featureDao)
indexer.indexLocation = GPKG_FIT_RTREE
let indexedCount = indexer.index()
// Query Indexed Features in paginated chunks
let indexResults: GPKGFeatureIndexResults = indexer.queryForChunk(with: boundingBox, in: projection, andLimit: 50)
let paginatedResults: GPKGRowPaginatedResults = indexer.paginate(indexResults)
do{
defer{paginatedResults.close()}
while(paginatedResults.moveToNext()){
let featureRow: GPKGFeatureRow = paginatedResults.userRow() as! GPKGFeatureRow
let geometryData: GPKGGeometryData! = featureRow.geometry()
if(geometryData != nil && !geometryData.empty){
let geometry: SFGeometry = geometryData.geometry
// ...
}
}
}
// Feature Tile Overlay (dynamically draw tiles from features)
let featureTiles: GPKGFeatureTiles = GPKGFeatureTiles(featureDao: featureDao)
featureTiles.maxFeaturesPerTile = 1000
let numberFeaturesTile: GPKGNumberFeaturesTile = GPKGNumberFeaturesTile()
featureTiles.maxFeaturesTileDraw = numberFeaturesTile
featureTiles.indexManager = indexer
let featureOverlay: GPKGFeatureOverlay! = GPKGFeatureOverlay(featureTiles: featureTiles)
featureOverlay.minZoom = NSNumber(value:featureDao.zoomLevel())
mapView.addOverlay(featureOverlay!)
// URL Tile Generator (generate tiles from a URL)
let urlTileGenerator: GPKGTileGenerator = GPKGUrlTileGenerator(geoPackage: geoPackage, andTableName: "url_tile_table", andTileUrl: "http://url/{z}/{x}/{y}.png", andMinZoom: 1, andMaxZoom: 2, andBoundingBox:boundingBox, andProjection:projection)
let urlTileCount: Int32 = urlTileGenerator.generateTiles()
// Feature Tile Generator (generate tiles from features)
let featureTileGenerator: GPKGTileGenerator = GPKGFeatureTileGenerator(geoPackage: geoPackage, andTableName: featureTable + "_tiles", andFeatureTiles: featureTiles, andMinZoom: 1, andMaxZoom: 2, andBoundingBox:boundingBox, andProjection:projection)
let featureTileCount: Int32 = featureTileGenerator.generateTiles()
// Close database when done
geoPackage.close()
// Close manager when done
manager.close()
构建
请参见有关 automake
和 glibtoolize
的说明(以上说明)。
使用 Xcode 和/或 CocoaPods 构建此仓库
pod repo update
pod install
在 Xcode 中打开 geopackage-ios.xcworkspace 或从命令行构建
xcodebuild -workspace 'geopackage-ios.xcworkspace' -scheme geopackage-ios build
从 Xcode 或命令行运行测试
xcodebuild test -workspace 'geopackage-ios.xcworkspace' -scheme geopackage-ios -destination 'platform=iOS Simulator,name=iPhone 14'
远程依赖
- Simple Features WKB (MIT 许可证 (MIT))- 简单特征已知二进制库
- Simple Features WKT (MIT 许可证 (MIT))- 简单特征已知文本库
- Simple Features Projection (MIT 许可证 (MIT))- 简单特征投影库
- OGC API Features JSON (MIT 许可证 (MIT))- OGC API Features JSON 库
- Color (MIT 许可证 (MIT))- 颜色库
- TIFF (MIT 许可证 (MIT))- 标签图像文件格式库