76 lines
2.4 KiB
Python
Executable File
76 lines
2.4 KiB
Python
Executable File
import geopandas as gpd
|
|
import fiona
|
|
import zipfile
|
|
import tempfile
|
|
import os
|
|
import shutil
|
|
|
|
def read_gdb(zip_path: str, layer: str = None):
|
|
if not zip_path.lower().endswith(".zip"):
|
|
raise ValueError("File GDB harus berupa ZIP yang berisi folder .gdb atau file .gdbtable")
|
|
|
|
tmpdir = tempfile.mkdtemp()
|
|
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
|
zip_ref.extractall(tmpdir)
|
|
|
|
macosx_path = os.path.join(tmpdir, "__MACOSX")
|
|
if os.path.exists(macosx_path):
|
|
shutil.rmtree(macosx_path)
|
|
|
|
gdb_folders = []
|
|
for root, dirs, _ in os.walk(tmpdir):
|
|
for d in dirs:
|
|
if d.lower().endswith(".gdb"):
|
|
gdb_folders.append(os.path.join(root, d))
|
|
|
|
if not gdb_folders:
|
|
gdbtable_files = []
|
|
for root, _, files in os.walk(tmpdir):
|
|
for f in files:
|
|
if f.lower().endswith(".gdbtable"):
|
|
gdbtable_files.append(os.path.join(root, f))
|
|
|
|
if gdbtable_files:
|
|
first_folder = os.path.dirname(gdbtable_files[0])
|
|
base_name = os.path.basename(first_folder)
|
|
gdb_folder_path = os.path.join(tmpdir, f"{base_name}.gdb")
|
|
|
|
os.makedirs(gdb_folder_path, exist_ok=True)
|
|
|
|
for fpath in os.listdir(first_folder):
|
|
if ".gdb" in fpath.lower():
|
|
shutil.move(os.path.join(first_folder, fpath), os.path.join(gdb_folder_path, fpath))
|
|
|
|
gdb_folders.append(gdb_folder_path)
|
|
# print(f"[INFO] Rebuilt GDB folder from nested structure: {gdb_folder_path}")
|
|
else:
|
|
# print("[DEBUG] Isi ZIP:", os.listdir(tmpdir))
|
|
shutil.rmtree(tmpdir)
|
|
raise ValueError("Tidak ditemukan folder .gdb atau file .gdbtable di dalam ZIP")
|
|
|
|
gdb_path = gdb_folders[0]
|
|
|
|
layers = fiona.listlayers(gdb_path)
|
|
# print(f"[INFO] Layer tersedia: {layers}")
|
|
|
|
chosen_layer = layer or (layers[0] if layers else None)
|
|
if not chosen_layer:
|
|
shutil.rmtree(tmpdir)
|
|
raise ValueError("Tidak ada layer GDB yang bisa dibaca.")
|
|
|
|
print(f"[DEBUG] Membaca layer: {chosen_layer}")
|
|
|
|
try:
|
|
gdf = gpd.read_file(gdb_path, layer=chosen_layer)
|
|
except Exception as e:
|
|
shutil.rmtree(tmpdir)
|
|
raise ValueError(f"Gagal membaca layer dari GDB: {e}")
|
|
|
|
if gdf.crs is None:
|
|
# print("[WARN] CRS tidak terdeteksi, diasumsikan EPSG:4326")
|
|
gdf.set_crs("EPSG:4326", inplace=True)
|
|
|
|
|
|
shutil.rmtree(tmpdir)
|
|
return gdf
|