12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Behavioral Guidelines (Binding)
Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.
1. Think Before Coding
Don't assume. Don't hide confusion. Surface tradeoffs.
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
2. Simplicity First
Minimum code that solves the problem. Nothing speculative.
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
3. Surgical Changes
Touch only what you must. Clean up only your own mess.
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it — don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
The test: Every changed line should trace directly to the user's request.
Exception — Tech debt must be fixed, not deferred: When you discover a real bug, broken behavior, or technical debt while working (even if it predates this change and you didn't introduce it), fix it — do not use "not introduced by this round / pre-existing" as a reason to leave it. Surface it, then handle it. (User directive, 2026-06-25, binding.) This overrides the "don't fix what isn't broken" bias above for genuine defects — it does not license cosmetic refactors or unrequested rewrites.
Do it yourself — never offload work you can do (User directive, 2026-06-25, binding):
If you have the tools to do something, DO IT — never tell the user to do it for you.
Read the logs yourself (%LOCALAPPDATA%/Geomative/Geopro3/logs/geopro_*.log via Bash/grep),
inspect data/fixtures yourself, build and link yourself (build.bat app via PowerShell),
diagnose by adding logging and then reading that log yourself. The ONLY things to ask the
user for are: (a) closing a running app so the exe can relink (LNK1104 — a lock only they can
release), and (b) genuine product decisions. Do not ask the user to read logs, inspect data,
run diagnostics, or interpret output — that is your job.
4. Goal-Driven Execution
Define success criteria. Loop until verified.
Transform tasks into verifiable goals:
- "Add validation" -> "Write tests for invalid inputs, then make them pass"
- "Fix the bug" -> "Write a test that reproduces it, then make it pass"
- "Refactor X" -> "Ensure tests pass before and after"
For multi-step tasks, state a brief plan:
1. [Step] -> verify: [check]
2. [Step] -> verify: [check]
3. [Step] -> verify: [check]
Project Overview
Geopro 3.0 desktop client: a geophysical exploration data visualization application (Qt 6 + VTK 9, C++17, Windows/MSVC). Replicates the core "Project Analysis View" from Geopro 3.0 web.
Tech stack: Qt 6.11 (QtWidgets) + VTK 9.6 + CMake/Ninja + MSVC 2022/2026 + vcpkg (non-Qt deps only) + ADS (docking) + GDAL/PROJ + OpenSSL + QtKeychain + Qwt.
Build System
Prerequisites: Visual Studio 2022/2026 (Desktop C++ workload), Git, vcpkg with
VCPKG_ROOT env var set. Qt 6.11.1 MSVC kit at D:/Qt/6.11.1/msvc2022_64. VTK 9.6.2
prebuilt at external/vtk-install. All Qt-dependent libs (VTK/ADS/QtKeychain) link
against the official MSVC Qt kit; only non-Qt deps (GDAL/PROJ/OpenSSL/Eigen/gtest/etc.)
come from vcpkg.
Rule: cmake / ninja / cl are NOT on PATH by default. Build only inside an
activated MSVC environment. build.bat handles this automatically via vswhere.
Primary: build.bat (recommended)
Run from repo root in cmd (not PowerShell for parameter passing):
| Command | Action |
|---|---|
build or build app |
Incremental build of geopro_desktop (default) |
build run |
Build and launch geopro_desktop.exe |
build test |
Build and run unit tests via ctest |
build all |
Build all targets |
build configure |
Force re-configure CMake (after CMakeLists changes or new sources) |
build rebuild |
Clean rebuild (--clean-first) then launch |
Alternative: Manual CMake
Open "x64 Native Tools Command Prompt for VS", then:
set CMAKE="%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe"
%CMAKE% --preset msvc-release
%CMAKE% --build build/release --target geopro_desktop
%CMAKE% --build build/release --target geopro_tests
ctest --test-dir build/release --output-on-failure
(Debug: replace msvc-release with msvc-debug and build/release with build/debug.)
Build Targets
geopro_desktop— Main executable atbuild/release/src/app/geopro_desktop.exegeopro_tests— Unit test executable, discovered by ctestrender_verify— Offline PNG render verification (tests/spike/)grid_contour_spike/slice_alpha_probe— Spike verification tools
Incremental builds: Changing .cpp/.hpp only needs --build. Changing
CMakeLists.txt or adding new source files needs build configure or --preset.
LNK1104: If linking fails with "file in use", close any running geopro_desktop.exe
first (the only thing to ask the user for).
Testing
Framework: Google Test for core/data/render; Qt Test (QSignalSpy) for
controller/net. Discovered via gtest_discover_tests with DISCOVERY_MODE PRE_TEST
(because Qt DLLs are copied POST_BUILD; discovering at build time would fail with
0xc0000135).
Running Tests
build test # All tests via build.bat
ctest --test-dir build/release --output-on-failure -R <pattern> # Filter by regex
Running a single test case (example):
# After building geopro_tests:
build\release\tests\geopro_tests.exe --gtest_filter="*ColorScale*"
Some render/data tests require PROJ_DATA (set automatically by ctest from the vcpkg
install tree). If running the test exe directly, ensure external/vtk-install/bin and
vcpkg DLLs are on PATH.
Render Verification
Rendering correctness must be verified with offline PNG pixel checks, not just
"doesn't crash". Use tests/spike/render_verify.cpp:
build all # builds render_verify
# Ensure PATH includes external/vtk-install/bin and vcpkg_installed/x64-windows/bin
# Ensure PROJ_DATA and GDAL_DATA are set if testing terrain/voxel
build\release\tests\spike\render_verify.exe
# Inspect output PNGs at D:/dev/spike_data/verify_*.png
Code Style
.clang-format: BasedOnStyle Google, C++17, 100 column limit, 4-space indent, braces after class/function..clangd: Compilation database atbuild/debug. Strict unused-include checks.- File encoding: UTF-8 without BOM. Do NOT use PowerShell
Set-Content -Encoding UTF8on source files (it corrupts Chinese comments).
Architecture
Six-layer directory structure under src/:
src/core/ Pure business logic. ZERO Qt/VTK includes. Independently unit-testable.
model/ (Project, ColorScale, Grid, ScalarVolume, Anomaly...)
geo/ (LocalFrame, GeoLocalFrame, CrsTransform)
algo/ (IInterpolator, IdwInterpolator, VolumeBuilder)
src/io/ I/O parsers. Pure C++17 where possible.
gpr/ (IprbReader, IprHeader, GprSurveyAssembler, GpsTrack)
src/data/ Data access layer. Async repository contracts (QFuture/cancel/paging).
repo/ (IAsyncProjectRepository, IDatasetRepository, LocalSampleRepository)
api/ (ApiDatasetRepository, ApiProjectRepository, NavRequest)
dto/ (JSON DTOs + mapping to domain models)
store/ (ChunkedVolumeStore, pyramid LOD, streaming writes)
src/net/ Network & auth. ApiClient, AuthService, RsaEncryptor, Credential (QtKeychain).
src/render/ VTK rendering layer. Owns ALL actors and the single vtkRenderWindow.
Scene.hpp is the single owner of the render window.
actors/ (ScatterActor, GridContourActor, CurtainActor, VoxelActor, AnomalyActor, TerrainActor, ElectrodeActor)
interact/ (InteractionManager, SliceTool, PickInteractorStyle, AnomalyDrawTool)
source/ (Volume render sources: WholeVolumeSource, OutOfCoreSource, ViewAdaptiveVolumeSource)
ground/ (TileMath for basemap tiles)
src/controller/ Orchestration. Signals/slots wired in wireUp() methods.
(WorkbenchNavController, DatasetDetailController, VtkSceneController)
src/app/ Entry point + MainWindow + all QtWidgets panels and dialogs.
panels/ (ObjectTreePanel, DatasetListPanel, DatasetDetailPanel, AnomalyListPanel, etc.)
panels/chart/ (Qwt-based detail charts: GridDataChartView, ScatterPlotItem, ContourPlotItem)
panels/columns/ (Category analysis tabs)
panels/web/ (ProjectWebView with QWebEngineView)
Architecture rules (binding):
coremust NEVER#includeany Qt or VTK header.- VTK actors /
vtkRenderWindoware created and owned ONLY byrender.view/appholds theQVTKOpenGLStereoWidgetshell but must NOT create actors directly. - Signal/slot connections are concentrated in
*Controller::wireUp()orMainWindow. - All file paths use
QStandardPaths(Qt) or project-relative logic; no hardcoded paths.
Coordinate System
- Data source CRS: EPSG:4547 (CGCS2000 / 3-degree Gauss-Kruger CM 114E) for
projectX/projectYin local survey data. - Project world coordinate:
core::GeoLocalFrame(lat/lon -> local meters, equidistant cylindrical), shared across all views for registration. - DEM/imagery: EPSG:3857 (Web Mercator), reprojected via PROJ/GDAL at runtime.
- Rendering convention: depth
yincreases downward -> VTKzis negated.
Key Dependencies & FetchContent
- Qt 6.11.1: Official MSVC kit at
D:/Qt/6.11.1/msvc2022_64.CMAKE_PREFIX_PATHpoints here. Only one Qt exists in the build. - VTK 9.6.2: Built from source against the same Qt, installed to
external/vtk-install. Required components includeGUISupportQt,RenderingOpenGL2,InteractionStyle,FiltersSources,RenderingVolumeOpenGL2,InteractionWidgets,FiltersGeometry,IOImage. - ADS (Qt-Advanced-Docking-System) 4.3.1: FetchContent from GitHub. Linked as
ads::qt6advanceddocking. - QtKeychain 0.14.0: FetchContent, static-linked.
BUILD_WITH_QT6=ON. - Qwt 6.2: Source expected at
external/qwt-src. Included viacmake/qwt.cmake. - vcpkg deps: eigen3, gdal, gtest, nlohmann-json, openssl, proj.
Important Project Conventions
- ColorScale / colorBar values: Use real non-uniform segment values from the dataset. Uniform grading produces incorrect all-blue renders.
- 2D map vs 3D view: These are different content, not the same scene with a
different camera. 2D map =
MapLineActor(survey line trajectories, top-down). 3D view =CurtainActor(vertical cross-section walls) + voxel + slice + terrain. - Data detail (bottom panel) = single-dataset analysis view (
GridContourActorfor #18 grid,ScatterActorfor #17 raw data). - Rendering changes must be verified with
render_verifyoffline PNG before app integration, then manually in-app. - Build and link yourself — do not ask the user to run builds, read logs, or inspect
data. The only exception is closing a running
geopro_desktop.exefor LNK1104.
Memory
- See
.claude/projects/E--gitea-geopro/memory/MEMORY.mdfor persistent project context.