diff --git a/lib/towerops/lidar/reader.ex b/lib/towerops/lidar/reader.ex index 93167bf3..9f464f11 100644 --- a/lib/towerops/lidar/reader.ex +++ b/lib/towerops/lidar/reader.ex @@ -58,26 +58,30 @@ defmodule Towerops.Lidar.Reader do @spec elevation_grid(Tile.t(), {number(), number(), number(), number()}, number()) :: {:ok, map()} | {:error, term()} def elevation_grid(%Tile{url: url}, {west, south, east, north}, cell_size_deg) do + # gdalwarp reprojects to EPSG:4326 on the fly. gdal_translate cannot + # reproject — it only crops in the source CRS — so 3DEP Albers tiles + # would otherwise come back in projected metres. args = [ "-of", "AAIGrid", - "-projwin_srs", + "-t_srs", "EPSG:4326", - "-projwin", + "-te", to_string(west), - to_string(north), - to_string(east), to_string(south), + to_string(east), + to_string(north), "-tr", to_string(cell_size_deg), to_string(cell_size_deg), - "-t_srs", - "EPSG:4326", + "-r", + "bilinear", + "-overwrite", vsicurl(url), "/vsistdout/" ] - case run("gdal_translate", args) do + case run("gdalwarp", args) do {output, 0} -> parse_aaigrid(output) {output, code} -> {:error, {:gdal, code, output}} end diff --git a/lib/towerops/workers/coverage_worker.ex b/lib/towerops/workers/coverage_worker.ex index 4bfb7cd9..03ff8f42 100644 --- a/lib/towerops/workers/coverage_worker.ex +++ b/lib/towerops/workers/coverage_worker.ex @@ -431,7 +431,15 @@ defmodule Towerops.Workers.CoverageWorker do defp describe_error({:terrain_unavailable, :nodata}), do: "LIDAR tiles for this area returned no data." - defp describe_error({:terrain_unavailable, reason}), do: "Terrain fetch failed: #{inspect(reason)}" + defp describe_error({:terrain_unavailable, {:gdal, _code, _output} = reason}) do + Logger.warning("CoverageWorker: GDAL failure: #{inspect(reason)}") + "Terrain data fetch failed. The TowerOps team has been notified — please retry shortly." + end + + defp describe_error({:terrain_unavailable, reason}) do + Logger.warning("CoverageWorker: terrain fetch failed: #{inspect(reason)}") + "Terrain data is temporarily unavailable for this site. Please retry shortly." + end defp describe_error({:unknown_antenna, slug}), do: "Antenna #{inspect(slug)} is not in the registry."