Spaces:
Running
Running
Guilherme Silberfarb Costa commited on
Commit ·
a20fa71
1
Parent(s): 02cb858
Harden portable shapefile diagnostics
Browse files
backend/app/core/shapefile_runtime.py
CHANGED
|
@@ -35,8 +35,44 @@ def _iter_features_pyshp(shapefile_path: Path, *, target_crs: str | None) -> lis
|
|
| 35 |
from shapely.geometry import shape
|
| 36 |
from shapely.ops import transform as shapely_transform
|
| 37 |
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
field_names = [str(field[0]) for field in reader.fields[1:]]
|
| 41 |
source_crs = None
|
| 42 |
prj_path = shapefile_path.with_suffix(".prj")
|
|
@@ -48,25 +84,45 @@ def _iter_features_pyshp(shapefile_path: Path, *, target_crs: str | None) -> lis
|
|
| 48 |
transformer = _build_transformer(source_crs, target_crs)
|
| 49 |
|
| 50 |
features: list[tuple[dict[str, Any], Any]] = []
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
geometry =
|
| 61 |
-
if
|
| 62 |
-
geometry =
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
return features
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
finally:
|
| 66 |
try:
|
| 67 |
-
reader
|
|
|
|
| 68 |
except Exception:
|
| 69 |
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
|
| 72 |
def _iter_features_fiona(shapefile_path: Path, *, target_crs: str | None) -> list[tuple[dict[str, Any], Any]]:
|
|
|
|
| 35 |
from shapely.geometry import shape
|
| 36 |
from shapely.ops import transform as shapely_transform
|
| 37 |
|
| 38 |
+
shp_path = shapefile_path.with_suffix(".shp")
|
| 39 |
+
shx_path = shapefile_path.with_suffix(".shx")
|
| 40 |
+
dbf_path = shapefile_path.with_suffix(".dbf")
|
| 41 |
+
|
| 42 |
+
def _describe_sidecars() -> str:
|
| 43 |
+
parts: list[str] = []
|
| 44 |
+
for candidate in (shp_path, shx_path, dbf_path, shapefile_path.with_suffix(".prj"), shapefile_path.with_suffix(".cpg")):
|
| 45 |
+
if candidate.exists():
|
| 46 |
+
try:
|
| 47 |
+
parts.append(f"{candidate.name}={candidate.stat().st_size}")
|
| 48 |
+
except Exception:
|
| 49 |
+
parts.append(f"{candidate.name}=present")
|
| 50 |
+
else:
|
| 51 |
+
parts.append(f"{candidate.name}=missing")
|
| 52 |
+
return ", ".join(parts)
|
| 53 |
+
|
| 54 |
+
if not shp_path.exists():
|
| 55 |
+
raise FileNotFoundError(f"Shapefile nao encontrado: {shp_path}")
|
| 56 |
+
|
| 57 |
+
handles = []
|
| 58 |
+
reader = None
|
| 59 |
try:
|
| 60 |
+
shp_handle = open(shp_path, "rb")
|
| 61 |
+
handles.append(shp_handle)
|
| 62 |
+
shx_handle = open(shx_path, "rb") if shx_path.exists() else None
|
| 63 |
+
if shx_handle is not None:
|
| 64 |
+
handles.append(shx_handle)
|
| 65 |
+
dbf_handle = open(dbf_path, "rb") if dbf_path.exists() else None
|
| 66 |
+
if dbf_handle is not None:
|
| 67 |
+
handles.append(dbf_handle)
|
| 68 |
+
|
| 69 |
+
reader = shapefile.Reader(
|
| 70 |
+
shp=shp_handle,
|
| 71 |
+
shx=shx_handle,
|
| 72 |
+
dbf=dbf_handle,
|
| 73 |
+
encoding="utf-8",
|
| 74 |
+
encodingErrors="replace",
|
| 75 |
+
)
|
| 76 |
field_names = [str(field[0]) for field in reader.fields[1:]]
|
| 77 |
source_crs = None
|
| 78 |
prj_path = shapefile_path.with_suffix(".prj")
|
|
|
|
| 84 |
transformer = _build_transformer(source_crs, target_crs)
|
| 85 |
|
| 86 |
features: list[tuple[dict[str, Any], Any]] = []
|
| 87 |
+
record_errors: list[str] = []
|
| 88 |
+
for index, shape_record in enumerate(reader.iterShapeRecords()):
|
| 89 |
+
try:
|
| 90 |
+
values = list(shape_record.record)
|
| 91 |
+
properties = {
|
| 92 |
+
field_name: values[field_index] if field_index < len(values) else None
|
| 93 |
+
for field_index, field_name in enumerate(field_names)
|
| 94 |
+
}
|
| 95 |
+
geometry_raw = getattr(shape_record.shape, "__geo_interface__", None)
|
| 96 |
+
geometry = None
|
| 97 |
+
if geometry_raw and geometry_raw.get("coordinates"):
|
| 98 |
+
geometry = shape(geometry_raw)
|
| 99 |
+
if transformer is not None:
|
| 100 |
+
geometry = shapely_transform(transformer.transform, geometry)
|
| 101 |
+
features.append((properties, geometry))
|
| 102 |
+
except Exception as exc:
|
| 103 |
+
if len(record_errors) < 5:
|
| 104 |
+
record_errors.append(f"registro {index}: {exc!r}")
|
| 105 |
+
continue
|
| 106 |
+
|
| 107 |
+
if not features and record_errors:
|
| 108 |
+
detalhe = "; ".join(record_errors)
|
| 109 |
+
raise RuntimeError(f"nenhum registro legivel via pyshp ({detalhe})")
|
| 110 |
return features
|
| 111 |
+
except Exception as exc:
|
| 112 |
+
raise RuntimeError(
|
| 113 |
+
f"pyshp falhou para {shapefile_path.name}: {exc!r}; arquivos: {_describe_sidecars()}"
|
| 114 |
+
) from exc
|
| 115 |
finally:
|
| 116 |
try:
|
| 117 |
+
if reader is not None:
|
| 118 |
+
reader.close()
|
| 119 |
except Exception:
|
| 120 |
pass
|
| 121 |
+
for handle in handles:
|
| 122 |
+
try:
|
| 123 |
+
handle.close()
|
| 124 |
+
except Exception:
|
| 125 |
+
pass
|
| 126 |
|
| 127 |
|
| 128 |
def _iter_features_fiona(shapefile_path: Path, *, target_crs: str | None) -> list[tuple[dict[str, Any], Any]]:
|
build/windows/smoke_test_portable.ps1
CHANGED
|
@@ -61,6 +61,16 @@ function Show-StartupDiagnostics {
|
|
| 61 |
Write-Host "--- MesaFrame-startup.log ---"
|
| 62 |
Get-Content -Path $startupLogPath
|
| 63 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
$proc = Start-Process -FilePath $exePath -WorkingDirectory $appDirResolved -PassThru
|
|
|
|
| 61 |
Write-Host "--- MesaFrame-startup.log ---"
|
| 62 |
Get-Content -Path $startupLogPath
|
| 63 |
}
|
| 64 |
+
$dadosDir = Join-Path $appDirResolved "_internal/app/core/dados"
|
| 65 |
+
if (Test-Path $dadosDir) {
|
| 66 |
+
Write-Host "--- dados bundle ---"
|
| 67 |
+
Get-ChildItem -Path $dadosDir | Select-Object Name, Length | Format-Table -AutoSize | Out-String | Write-Host
|
| 68 |
+
}
|
| 69 |
+
$logoPath = Join-Path $appDirResolved "_internal/frontend/dist/logo_mesa.png"
|
| 70 |
+
if (Test-Path $logoPath) {
|
| 71 |
+
Write-Host "--- logo bundle ---"
|
| 72 |
+
Get-Item $logoPath | Select-Object FullName, Length | Format-Table -AutoSize | Out-String | Write-Host
|
| 73 |
+
}
|
| 74 |
}
|
| 75 |
|
| 76 |
$proc = Start-Process -FilePath $exePath -WorkingDirectory $appDirResolved -PassThru
|