在Python中处理GDB、MDB和Shapefile文件转换
在Python中处理GDB、MDB和Shapefile文件转换,有多种库可以使用。以下是常用的方法和工具:
主要工具库
1. GDAL/OGR
最强大的地理数据处理库,支持多种格式:
python
from osgeo import ogr# GDB/MDB转Shapefile def gdb_to_shp(gdb_path, output_shp):driver = ogr.GetDriverByName('FileGDB')gdb_ds = driver.Open(gdb_path, 0)for i in range(gdb_ds.GetLayerCount()):layer = gdb_ds.GetLayer(i)shp_driver = ogr.GetDriverByName('ESRI Shapefile')shp_ds = shp_driver.CreateDataSource(f"{output_shp}_{layer.GetName()}.shp")shp_ds.CopyLayer(layer, layer.GetName())shp_ds = Nonegdb_ds = None# MDB转Shapefile def mdb_to_shp(mdb_path, output_shp):driver = ogr.GetDriverByName('PGeo')mdb_ds = driver.Open(mdb_path, 0)for i in range(mdb_ds.GetLayerCount()):layer = mdb_ds.GetLayer(i)shp_driver = ogr.GetDriverByName('ESRI Shapefile')shp_ds = shp_driver.CreateDataSource(f"{output_shp}_{layer.GetName()}.shp")shp_ds.CopyLayer(layer, layer.GetName())shp_ds = Nonemdb_ds = None
2. Fiona
更Pythonic的地理数据处理库:
python
import fiona# GDB转Shapefile def convert_gdb_to_shp(gdb_path, output_dir):with fiona.open(gdb_path, 'r', driver='FileGDB') as gdb:for layer_name in gdb.layer_names:with fiona.open(gdb_path, 'r', layer=layer_name, driver='FileGDB') as layer:output_path = f"{output_dir}/{layer_name}.shp"# 创建输出schemaoutput_schema = layer.schemawith fiona.open(output_path, 'w', driver='ESRI Shapefile',schema=output_schema,crs=layer.crs) as output:for feature in layer:output.write(feature)# 使用示例 convert_gdb_to_shp('input.gdb', './output')
3. GeoPandas
适合数据分析和处理的库:
python
import geopandas as gpd import osdef convert_gdb_to_shapefiles(gdb_path, output_folder):# 获取GDB中的所有图层layers = gpd.list_layers(gdb_path)for layer_name in layers:# 读取图层gdf = gpd.read_file(gdb_path, layer=layer_name)# 输出路径output_path = os.path.join(output_folder, f"{layer_name}.shp")# 保存为Shapefilegdf.to_file(output_path, driver='ESRI Shapefile')print(f"已转换: {layer_name} -> {output_path}")# 使用示例 convert_gdb_to_shapefiles('input.gdb', './shapefiles')
完整转换脚本
python
import os from osgeo import ogr import geopandas as gpdclass GeodatabaseConverter:def __init__(self):self.supported_drivers = {'gdb': 'FileGDB','mdb': 'PGeo','shp': 'ESRI Shapefile'}def convert(self, input_path, output_dir, output_format='shp'):"""转换地理数据库文件Args:input_path: 输入文件路径output_dir: 输出目录output_format: 输出格式 ('shp', 'geojson', etc.)"""# 检测输入文件类型if input_path.endswith('.gdb'):driver_name = self.supported_drivers['gdb']elif input_path.endswith('.mdb'):driver_name = self.supported_drivers['mdb']else:raise ValueError("不支持的输入格式")# 打开数据源driver = ogr.GetDriverByName(driver_name)source_ds = driver.Open(input_path, 0)if source_ds is None:raise Exception(f"无法打开文件: {input_path}")# 创建输出目录os.makedirs(output_dir, exist_ok=True)# 遍历所有图层for i in range(source_ds.GetLayerCount()):layer = source_ds.GetLayer(i)layer_name = layer.GetName()# 输出文件路径output_path = os.path.join(output_dir, f"{layer_name}.{output_format}")# 创建输出数据源out_driver = ogr.GetDriverByName(self.supported_drivers.get(output_format, output_format))if out_driver is None:out_driver = ogr.GetDriverByName('ESRI Shapefile')out_ds = out_driver.CreateDataSource(output_path)out_ds.CopyLayer(layer, layer_name)out_ds = Noneprint(f"转换完成: {layer_name} -> {output_path}")source_ds = None# 使用示例 if __name__ == "__main__":converter = GeodatabaseConverter()# 转换GDBconverter.convert('input.gdb', './output_shapefiles')# 转换MDBconverter.convert('input.mdb', './output_shapefiles')
安装依赖
bash
# 使用conda(推荐) conda install gdal fiona geopandas# 使用pip pip install gdal fiona geopandas pyogrio
注意事项
GDAL版本:确保安装正确版本的GDAL,不同版本对GDB/MDB的支持可能不同
文件路径:GDB是文件夹,MDB是单个文件
编码问题:中文路径或字段名可能需要特殊处理
大文件处理:对于大型数据库,建议分批处理
高级功能
python
# 批量处理多个文件 def batch_convert(input_dir, output_dir, file_ext='.gdb'):converter = GeodatabaseConverter()for root, dirs, files in os.walk(input_dir):for item in dirs if file_ext == '.gdb' else files:if item.endswith(file_ext):input_path = os.path.join(root, item)output_subdir = os.path.join(output_dir, os.path.splitext(item)[0])converter.convert(input_path, output_subdir)# 转换坐标系 def convert_with_reprojection(input_path, output_path, target_crs='EPSG:4326'):gdf = gpd.read_file(input_path)gdf = gdf.to_crs(target_crs)gdf.to_file(output_path)
这些工具和方法应该能够满足大多数GDB、MDB到Shapefile的转换需求。根据你的具体需求选择合适的库和方法。