Terrain Analyzer – Technical Details

Back to Demo

High-Level System Overview

  • Purpose: Generate hillshade and heatmap raster outputs from dense grid inputs and render the results as a browser-visible raster grid.
  • Business problem: Demonstrates imagery/terrain analysis patterns where raw numeric grids are transformed into visualization-ready products for GIS users.
  • Architecture: Razor Page controls → /api/v1/raster endpoints → IRasterTerrainService → optional raster_terrain_kernel native library → managed fallback.
  • Technologies: .NET 10, Razor Pages, Bootstrap, vanilla JavaScript, C++20/CMake, P/Invoke, dense numeric arrays.
  • Scope: The MVP uses generated elevation and weighted point samples. It does not yet ingest GeoTIFF, COG, or GDAL-backed datasets.

Frontend Architecture

  • Page: Pages/Projects/Terrain/Index.cshtml exposes raster dimensions, hillshade azimuth, and operation buttons.
  • Script: wwwroot/js/Terrain/app.js generates deterministic sample elevation grids and heatmap point sets, then posts to the backend through apiPost.
  • Rendering: Hillshade values render as grayscale cells; heatmap values render as normalized red-opacity cells.
  • UX: KPI cards expose cell count, native/fallback mode, and active operation so the demo can support a technical walkthrough.
  • Future ArcGIS path: The same output could be encoded as PNG tiles or exposed through an ArcGIS-compatible tile endpoint.

API Layer

  • Controller: RasterTerrainController is versioned at /api/v1/raster and allows anonymous demo access.
  • Endpoints: POST /api/v1/raster/hillshade accepts RasterHillshadeRequestDto; POST /api/v1/raster/heatmap accepts HeatmapRequestDto.
  • Responses: RasterHillshadeResultDto returns 8-bit intensity values; HeatmapResultDto returns normalized floating-point raster values.
  • Validation: The service verifies positive dimensions, expected raster length, positive cell size/radius, and valid extents.
  • Error handling: Invalid input maps to the standard 400 response shape; unexpected failures are handled by middleware.

Services and Business Logic

  • Service: RasterTerrainService validates raster requests and dispatches to RasterTerrainNativeBridge when available.
  • Hillshade fallback: Samples neighboring cells, computes approximate slope/aspect, applies sun azimuth/altitude, and emits an 8-bit intensity grid.
  • Heatmap fallback: Applies a Gaussian-style kernel from weighted points over a target raster extent, then normalizes output values.
  • Native bridge: RasterTerrainNativeBridge passes dense arrays and preallocated output buffers into C++ and maps the returned buffers to DTOs.
  • C++ library: native/raster_terrain_kernel exposes Raster_GenerateHillshade and Raster_GenerateHeatmap.
  • Why C++ here: Raster analysis is dense numeric grid processing where SIMD, cache locality, and low-level memory control can materially affect tile-generation latency.

Data Access Layer

  • Current MVP: No PostgreSQL persistence is used; raster inputs are generated client-side and processed per request.
  • Reasoning: The MVP isolates the compute kernel and avoids introducing heavy raster storage before the API and UI shape are proven.
  • Future storage: Real DEM/imagery metadata could live in PostgreSQL while raster files live in object storage or a cloud-native tile store.
  • Cache path: Redis could cache generated tiles by z/x/y or by request hash once tile endpoints are introduced.

Infrastructure and Deployment

  • Native build: native/raster_terrain_kernel/CMakeLists.txt builds the shared library with AVX2-friendly compiler flags and copies it to the .NET output directory.
  • Runtime fallback: The service uses managed C# when the native library is absent, keeping Render deployment portable.
  • Dependency strategy: The MVP avoids GDAL to keep deployment light. A production raster pipeline would likely add GDAL/PROJ and document their image-size and runtime-package implications.
  • Scale-out path: Tile caching, precomputed pyramids, and queue-backed raster jobs are natural next steps for larger datasets.

Engineering Decisions and Tradeoffs

  • Grid output over image tiles: The current UI is transparent and easy to inspect, but real map overlays should use PNG or vector-tile style endpoints.
  • Generated data: Keeps the demo self-contained, but does not test file ingestion, georeferencing, nodata handling, or reprojection.
  • Native kernel boundary: Dense arrays are a good P/Invoke fit because they avoid object-heavy marshalling and keep memory layout predictable.
  • Future improvements: Add slope/aspect outputs, PNG tile generation, GeoTIFF/COG ingestion, GDAL integration, native benchmarks, and ArcGIS raster overlay rendering.

Interview Discussion Points

  • Why are raster kernels stronger SIMD candidates than graph traversal or topology validation?
  • Where would GDAL fit, and what deployment cost would it add?
  • How would tile caching change API design and frontend rendering?
  • How would you validate numeric parity between native and managed raster outputs?