24 KiB
Strict Qt6 Migration Prompt: ArcGIS 300 Symbology — verify & complete the SituationMap + AdvancedSymbology migration
This prompt is binding task context. Keep changes minimal, scoped, and reproducible.
The only allowed outcome is a fully-verified ArcGIS-300 symbology migration in
qt6-after/qt6-migrated-legatus in which every migrated symbology file preserves the
legacy Qt5 behavior except for the approved Qt5→Qt6 / ArcGIS-Maps-SDK-300 API
adaptations. No behavior change is allowed in the ON-variant (validated) build.
ArcGIS version in use: ArcGIS Maps SDK for Qt 300.0.0
(external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk).
Required base prompts
Before making changes, read and apply:
- ./prompts/combined-migration-subfolder-rti-compact.prompt.md
- ./prompts/commit-policy.prompt.md (repository mapping, pre-commit checks, per-repo commits)
If a base prompt is stricter, follow it. This prompt adds:
- build variants: ON variants only for
BUILD_RTI/BUILD_GRANTLEE; validation usesBUILD_ARCGIS=ON(this is not an RTI/Grantlee OFF variant — the prohibition on OFF RTI/Grantlee does not apply to ArcGIS) - scope: the symbology subsystem (SituationMap + AdvancedSymbology), ArcGIS 300.0.0
Task
Verify — and where the migration is incomplete or diverges from legacy, complete — the ArcGIS 300 migration of the symbology subsystem:
- the SituationMap viewer's military (SIDC) symbology:
Symbology/,SymbologyImpl/,SymbologyXML/(the pure-Qt SIDC codec/builder/dictionary plus the Esri dictionary-symbol processors that parse ArcGIS.styledictionaries) - the ArcGIS map layer:
SituationMap/Map/(now on the new ArcGIS Maps SDK for Qt 300.0.0) - the AdvancedSymbology plugin:
Lts/Plugins/AdvancedSymbology/(symbol editor, symbol proxy, data plugin, helper renderer) - the one remaining ArcGIS-dependent service file:
Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp
For every file in scope, diff it against the legacy Qt5 tree and prove each hunk is migration-only (or restore it to the legacy semantics with approved adaptations, or report a blocker).
Branches and trees
Working repository (a separate git repo; never commit its changes into the workspace root or the legacy repository):
./qt-migration-legatus
Trees:
- Legacy Qt5 source tree (read-only reference, never modify):
./qt-migration-legatus/qt5-before/qt5-legatus-legacy - Qt6 target tree (the only tree that is modified):
./qt-migration-legatus/qt6-after/qt6-migrated-legatus
Working branch: the dedicated ArcGIS-300 symbology branch the user created for this work
(verify its name with git branch --show-current; do not conflate it with the main
migration branch).
Before starting:
git fetch originin./qt-migration-legatus.- Confirm the working tree state with
git status --short. Known state at prompt writing (2026-10-06): the main worktree is onfeature/qt6-migration-projects-app-tools-viewer-validation-tetraifat1e07bf76b("Add ddsview topic-type-plugin deps to GROUP6") with two uncommitted files —qt6-after/qt6-migrated-legatus/new_docker_build.sh(theensure_databasestep) andqt6-after/qt6-migrated-legatus/tests/CMakeLists.txt(10migration_teststarget-guard fixes). Do not lose these: if they are not part of this task, commit or stash them on their own branch first; do not fold unrelated changes into the symbology commit. - Confirm both trees exist and that the ArcGIS SDK 300.0.0 directory exists at the path below. If the working tree has unrelated uncommitted changes that block safe work, report the blocker.
What is already established (verified 2026-10-06 — starting state; re-verify cheaply)
Treat the following as the verified starting state. Re-run the cheap checks to confirm the current state, but do not re-derive the whole picture.
- The migration STUBBED almost all ArcGIS. Legacy
Lts/Vieweruses the OLD ArcGIS Runtime SDK (100.x) with 399#include <arcgis/...>. The migrated tree has 11 arcgis includes total, all in:Lts/Viewer/SituationMap/Map/situation_map_utils.h(SceneViewTypes.h, Error.h)Lts/Viewer/SituationMap/Map/situation_map_utils.cpp(CoreTypes.h, MapTypes.h, Viewpoint.h, Camera.h, arcgisversion.h)Lts/Viewer/SituationMap/Map/map_initializer.cpp(arcgisversion.h)Lts/Viewer/SituationMap/Map/layer_factory.h(arcgisversion.h)Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp(PolygonBuilder.h, GeometryEngine.h)
Lts/Viewer/SituationMap/ElevationMap/(7 files in legacy) is removed entirely in the migrated tree. Do not restore it unless this task explicitly requires it.- The SIDC symbology (
Symbology/,SymbologyImpl/,SymbologyXML/) is pure Qt — zero arcgis includes. The ArcGIS dependency is confined to the map layer and the one service file above. - The migrated arcgis includes use the new 300.0.0 header names (
MapTypes.h,Viewpoint.h,Camera.h,CoreTypes.h,SceneViewTypes.h,PolygonBuilder.h,GeometryEngine.h,arcgisversion.h) and keep theEsri::ArcGISRuntime::namespace (e.g.Esri::ArcGISRuntime::SymbolStyleSearchResultinSymbologyImpl/esri_dictionary_processor.cpp). The include style is inconsistent: some keep thearcgis/prefix (#include <arcgis/Viewpoint.h>), some drop it (#include <TaskWatcher.h>). This must be reconciled (see step 6 of the procedure). - Audit baseline (2026-10-06, CRLF-ignored diff of files present in both trees):
- SituationMap: 96 common source files differ, ~1149 changed lines, all migration-only so far.
- AdvancedSymbology: 37 common source files differ (no added/removed source files).
- The Esri dictionary processors (
esri_dictionary_processor*.cpp) changed only includes (#include <arcgis/X.h>→#include <X.h>, Qt include-path churn,qAsConst→std::as_const); the Esri types and symbol-search logic are unchanged.
Scope (the files to audit)
Audit, diff-vs-legacy, and classify every source file in:
Lts/Viewer/SituationMap/Symbology/— SIDC codec/builder/dictionary/definitions (sidc_codec.*,sidc_builder*.*,symbol_dictionary*.*,symbol_properties.*,symbol_result.*,sidc_definitions.*,bulk_renderer.*,property_result.*,result_watcher.*,symbol_data_to_render*.*,symbology_type.*, …).Lts/Viewer/SituationMap/SymbologyImpl/—esri_dictionary_processor*.cpp/.h(esri_dictionary_processor,..._app6,..._app6d,..._mil2525d),base_symbol_model.*,symbol_dictionary_impl.*,symbol_extension_renderer.*,advanced_symbology_logging.*.Lts/Viewer/SituationMap/SymbologyXML/—symbol.*,symbol_reader.*,symbol_writer.*,symbol_exporter.*,symbol_table.*,pixmap_symbol_cache.*,symbol_custom_graphics_item_group.*,attribute_data.h,symbol_types.h,xml_symbol_codec.h,Gui/symbol_dialog.*.Lts/Viewer/SituationMap/Map/— the ArcGIS map layer (57 files):map.*,map_initializer.*,layer_factory.h,situation_map_utils.*,camera.*,fill_style.*,line_style.*,geometry_model_renderer.*,object_container.*,object_factory.*,map_settings.*,operator_map_settings.*,map_notifier.*,bounding_box.*,grid.h,measurement.h, … and every sibling present in the dir.Lts/Plugins/AdvancedSymbology/(37 files):Data/asb_data_plugin.*,Data/asb_foreign_interface_impl.*,Data/logger.*,Gui/SymbolEditor/*,Gui/SymbolProxy/*,Helper/table_model_symbol_renderer*.*, and theasb_*_interface.hheaders.Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp.
Do not touch ElevationMap/ (removed) unless the task requires restoring it.
Expected migration patterns (each must verify as migration-only)
These are the changes seen in the baseline audit. Each is an approved adaptation; when you
see one, confirm it is the exact legacy-equivalent transformation and leave it. If a file
deviates from the pattern (extra/missing logic), classify it as semantic-change and act.
- Qt include path churn:
#include <QX>→#include <QtCore/QX>(andQtGui/,QtWidgets/,QtMultimedia/,QtNetwork/,QtSql/,QtXml/,QtPrintSupport/). qAsConst(x)→std::as_const(x)(Qt6 removedqAsConst).QRegExp::exactMatch(s)→QRegularExpression::match(s).hasMatch();QRegExp→QRegularExpression(type + include).QString::count()→QString::size()(count()removed in Qt6).QString::leftRef(n)→QString::left(n)(leftRefremoved in Qt6; a// Qt6: leftRef removednote may accompany it).QString::split(...): in Qt6 theQStringViewoverload is gone andsplit()returnsQStringList. Sites may now useQVector<QStringView>orQStringList— verify the chosen type is behavior-identical (same element order/values, samelast()/indexing).- New
const QStringView &overloads added to the SIDC codec helpers (decodeSymbology,decodeSidc,encodeBaseSymbolCode,encodeComplete,encodeCivilEts,encodeCivilXml) that delegate to theQStringoverloads (.toString()). Verify the delegate body is an exact pass-through. - ArcGIS include path: old
<arcgis/X.h>→ the SDK-300 layout. Reconcile to ONE consistent form (see procedure step 6) that matches how the CMake sets the SDK include path. const QImage &img = x.image()→const QImage img = x.image()(Qt6QImage::image()returns by value).
Verify carefully (potential behavior changes — do NOT auto-accept)
These are the non-obvious changes. For each, prove the legacy semantics are preserved in the validated (ON) build, or report a blocker. Files are given so you do not hunt.
ParticipantManagement::Role_def::*→Role::*— fileLts/Viewer/SituationMap/Symbology/symbol_data_to_render_role.h. Legacy references the DDS-generated enumerator setRole_def; migrated referencesRole. This is a DDS-generated-type rename. VERIFY the enum value mapping is 1:1 — everyRole_def::X→Role::Xwith the same numeric value/meaning (Unknown,Friend,Neutral,Enemy,Pending,AssumedFriend,Suspect, …). If the generatedRoleenum dropped, added, or reordered any enumerator, flag it (the value→role mapping must be preserved).#ifdef BUILD_WITH_EXTERNAL_DDSrole-conversion stub — filesLts/Viewer/SituationMap/Symbology/symbol_data_to_render_role.handLts/Plugins/AdvancedSymbology/Data/asb_foreign_interface_impl.{h,cpp}. When external DDS types are absent,roleToRole(...)returnsRole::Unknown(a STUB) instead of the real conversion. This is a runtime behavior change vs legacy. Confirm: (a) the real path (external-DDS available) still matches legacy 1:1; (b) the STUB path is never the one exercised in the validated ON build; (c) the stub is documented as intentional migration scaffolding. Do NOT "fix" the stub to look real, and do NOT let it leak into the validated build.- Logger pattern — files
Lts/Viewer/SituationMap/SymbologyImpl/ advanced_symbology_logging.{h,cpp},symbol_dictionary_impl.cpp,esri_dictionary_processor.cpp,base_symbol_model.cpp. LegacyLOGGER_T m_logger = getLogger("...")(local) → migrated memberNGL::INGLLogger &m_loggerinitialized in the constructor (, m_logger(getLogger(...))). Matches the known export-header/logger migration pattern. VERIFY there is no double-allocation, lifetime, or initialization-order issue, and the logger name string is unchanged. - QAbstractItemModel filter API — file
Lts/Viewer/SituationMap/SymbologyImpl/base_symbol_model.cpp. LegacyinvalidateFilter()→ migratedbeginFilterChange()/endFilterChange()(Qt6 removedinvalidateFilter()). VERIFY everyinvalidateFilter()call is correctly wrapped (abeginFilterChange()before the change and anendFilterChange()after), preserving the same filtering semantics.
Mandatory build variants
Only these variants are valid for validation:
BUILD_RTI=ONBUILD_GRANTLEE=ONBUILD_ARCGIS=ON
Forbidden: BUILD_RTI=OFF, BUILD_GRANTLEE=OFF. Do not implement, fix, preserve, test, or
validate OFF variants of BUILD_RTI/BUILD_GRANTLEE (no CMake logic, tests, stubs, or
fallbacks for them). BUILD_ARCGIS must be ON for this task (the ArcGIS map layer is
the point). The #ifdef BUILD_ARCGIS / #ifdef BUILD_WITH_EXTERNAL_DDS guards and their
STUB fallbacks are accepted migration scaffolding, but the validated build must use the
real, legacy-faithful (ON) path.
Preservation rules
- Migration-only: every change must be justified against the legacy Qt5 source at the same relative path. No behavior change in the ON-variant / validated build.
- No refactoring, no style cleanup, no warning suppression, no new features, no opportunistic modernization.
- Do not restore removed modules or the
ElevationMap/directory unless this task explicitly requires it. - Never commit generated outputs. No fake/dummy/stub files beyond the accepted
BUILD_ARCGIS/BUILD_WITH_EXTERNAL_DDSscaffolding that already exists. - Any required existing stub/forward declaration must live only under
qt6-after/qt6-migrated-legatus/forward-declarations/orqt6-after/qt6-migrated-legatus/.forward-declarations/include/; do not leave such files in service/plugin directories. - Keep the
Esri::ArcGISRuntime::*type names (do not "modernize" them away). - Keep the SIDC symbology pure-Qt: do not introduce arcgis includes into
Symbology/,SymbologyImpl/, orSymbologyXML/(they have none today).
Legacy comparison (required validation step)
This step proves the migration did not change code behavior.
Reference audit command (reproduce; CRLF-ignored, only files present in both trees):
cd ./qt-migration-legatus
LEG=qt5-before/qt5-legatus-legacy/Lts/Viewer/SituationMap
MIG=qt6-after/qt6-migrated-legatus/Lts/Viewer/SituationMap
: > /tmp/sym_cr.diff; n_real=0
while IFS= read -r rel; do
if [[ -f "$LEG/$rel" && -f "$MIG/$rel" ]] && ! diff -q "$LEG/$rel" "$MIG/$rel" >/dev/null 2>&1; then
if diff -q --strip-trailing-cr "$LEG/$rel" "$MIG/$rel" >/dev/null 2>&1; then :; else
n_real=$((n_real+1)); diff -u --strip-trailing-cr "$LEG/$rel" "$MIG/$rel" >> /tmp/sym_cr.diff
fi
fi
done < <(cd "$LEG" && find . -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | sed 's#^\./##' | sort)
echo "files with real changes: $n_real"
For every file you edit (and, as a sweep, every in-scope file):
- Read the legacy Qt5 source at the same relative path in
./qt-migration-legatus/qt5-before/qt5-legatus-legacy. If the file does not exist there (e.g. a pure-Qt6 scaffolding header), say so and compare against the pre-migration baseline. - Produce the audit diff: migrated result vs legacy (CRLF-ignored).
- Classify every hunk of the audit diff into exactly one category:
qt6-api: mandatory Qt5→Qt6 API adaptation (the pattern list above)sdk300-api: mandatory ArcGIS old-SDK → Maps-SDK-300 adaptationbuild: CMake/docker/test-infra change with no runtime semanticsstub-scaffolding: an accepted#ifdef BUILD_ARCGIS/BUILD_WITH_EXTERNAL_DDSguard (documented, OFF-path only)semantic-change: anything else
- Every
semantic-changehunk is a failure of this task unless you can point to the legacy source line that implements the same behavior. Fix it back to the legacy semantics (with approved adaptations) or report it as a blocker. Do not silently acceptsemantic-changehunks. - Record the per-file hunk classification (counts per category is sufficient; list every
semantic-changehunk explicitly) in the final report.
Docker and CI
- Authoritative validation script:
./qt-migration-legatus/qt6-after/qt6-migrated-legatus/new_docker_build.sh - Prebuilt image
legatus-qt6-prebuilt:latest(has local PostgreSQL; the DB is auto-provisioned by theensure_databasestep — no office DB needed). - ArcGIS SDK under
/workspace/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/ qt300.0.0/sdk(mounted from the pipeline rootexternal/); repo root at/workspace. new_docker_build.shis the single validation script; do not reintroduce a second script.
Required procedure
- Read the base prompts.
git fetch origin; confirm the working branch and the working- tree state (protect the two uncommitted files from "Branches and trees"). - Confirm the ArcGIS SDK 300.0.0 directory exists at the pipeline-root
external/path (and therefore/workspace/external/...in the container). - Re-run the audit command over
SituationMap/andLts/Plugins/AdvancedSymbology/(CRLF-ignored); confirm the baseline (SituationMap ~96 files, AdvancedSymbology 37 files, all migration-only). Record any drift. - For each in-scope file, diff vs legacy and classify every hunk (see "Legacy comparison").
Fix any
semantic-changeback to legacy semantics (with approved adaptations) or report a blocker. - Resolve the four "Verify carefully" items (Role value mapping; the DDS roleToRole stub real-path vs legacy; the logger pattern; the filter API pairing).
- Reconcile the ArcGIS include style (the
arcgis/prefix question) across the 11 migrated arcgis includes to ONE consistent form that matches the SDK 300 include path set in CMake. Record which form you chose and why. - Confirm the Esri dictionary processors still parse the same
.style/ MIL-STD-2525D / App-6 / App-6D dictionaries as legacy (sameEsri::ArcGISRuntime::*types, same symbol results; only includes changed). - Build the symbology targets with
BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=ON(the Viewer/SituationMap targets + the AdvancedSymbology plugin targets +expand_polygon) and confirm they compile and link against the 300.0.0 SDK. - Run the relevant CTest tests.
- Create the commit(s) (see "Commits").
- Report factual status and write the summary (see "Summary").
Do not push. The result stays local on the working branch until the user says otherwise.
Required validation
Targeted (fast, focused) — from the repo root, in the validation container (repo at
/workspace):
cmake -S /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus \
-B /workspace/build-arcgis300-symbology -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DBUILD_RTI=ON -DBUILD_GRANTLEE=ON -DBUILD_ARCGIS=ON \
-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON \
-DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/
# Discover the exact SituationMap + AdvancedSymbology target names from the
# SituationMap/AdvancedSymbology CMakeLists (or new_docker_build.sh's GROUP5_TARGETS),
# then build only those (faster than the whole tree):
cmake --build /workspace/build-arcgis300-symbology --target <situationmap_target> \
<asb_symbol_editor> <asb_symbol_proxy> <asb_data_plugin> --parallel
ctest --test-dir /workspace/build-arcgis300-symbology --output-on-failure
End-to-end via the validation script (the Viewer group carries the SituationMap targets;
also build the group that owns the AdvancedSymbology plugin targets — identify it from
GROUPn_TARGETS in new_docker_build.sh):
cd ./qt-migration-legatus/qt6-after/qt6-migrated-legatus
BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=ON ./new_docker_build.sh \
--use-prebuilt-image --docker-image legatus-qt6-prebuilt:latest --group5
Mandatory positive checks:
- The SituationMap map layer compiles and links against the ArcGIS Maps SDK 300.0.0 targets
(no undefined
Esri::ArcGISRuntime::*refs; no Qt5 imported-target links). - The Esri dictionary-symbol processors build and the SIDC codec/dictionary tests pass (same symbol results as legacy for the same inputs).
- The AdvancedSymbology plugin targets build.
- No
***Failed/***TimeoutCTest entries beyond documented base-state failures (record any base-state failures as base state, do not weaken a test to make it pass). - No active Qt5 imported-target links (
Qt5::,find_package(Qt5,Qt5Core, …) in the touched targets.
Do not run or validate OFF variants of BUILD_RTI/BUILD_GRANTLEE.
Commits
Commits on the working branch:
- Single author — the user's git identity (berrux-dev berrux.kana@axilinx.com). The user is the only author; do NOT add any co-author, co-authored-by, or bot attribution lines of any kind.
- Message: maximum 2 lines (one subject line plus at most one short body line), no blank-line
separators, no extra metadata. Subject example:
Qt6: verify/complete ArcGIS 300 symbology migration (SituationMap + AdvancedSymbology) - The repository has
commit.gpgsign=false: sign every created commit explicitly (git commit -S). Follow./prompts/commit-policy.prompt.mdfor repository mapping and pre-commit checks. If signing is not configured in this repository context, stop and report the exact reason instead of committing unsigned. - Keep the two unrelated uncommitted files (
new_docker_build.shDB step,tests/CMakeLists.txtguard fixes) OUT of the symbology commit unless the user says otherwise. - If a fix requires an additional commit, the same 2-line / single-author / no-attribution / signed rules apply.
Success criteria
Success requires:
- every in-scope file diffed vs legacy and every hunk classified; zero unexplained
semantic-changehunks (each one either fixed to legacy semantics or reported as a blocker) - the four "Verify carefully" items resolved with evidence (Role 1:1 mapping; the DDS roleToRole stub real-path matches legacy and does not leak into the ON build; the logger pattern is sound; the filter API pairing is correct)
- the 11 migrated arcgis includes reconciled to ONE consistent include style (recorded)
- the Esri dictionary processors confirmed to parse the same dictionaries as legacy
- configure, build (link), and CTest pass with
BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=ONfor the symbology targets - no active Qt5 imported-target links in the touched targets; generated outputs build-tree only, never committed; no fake/dummy/stub files beyond the accepted scaffolding
- required stubs/forward declarations only in allowed directories
- no OFF-variant logic/stubs for
BUILD_RTI/BUILD_GRANTLEEintroduced - the commits are signed (verify Good), single-author, ≤2-line, no bot attribution
- no push performed
If blocked
Do not fake success. Report:
- failing command and key error output
- affected file/branch
- category: project, path, CMake, Qt API, ArcGIS-SDK-300, DDS-generated-types, codegen, Docker, RTI/license, test, CTest, stub scaffolding, or environment
- the specific in-scope file and hunk, and which category it was misclassified as
- what was resolved safely, what remains blocked
- whether stale artifacts were ruled out
- whether generated files or the ArcGIS SDK path were involved
- the legacy comparison status for the unresolved files
Final report
Keep it short. Include:
- status: validated, partially validated, or blocked
- the working branch name and the commit hash(es) (signed)
- the re-run audit baseline (SituationMap / AdvancedSymbology file + changed-line counts) and any drift vs the 2026-10-06 baseline
- per-scope-area hunk counts by category, and every
semantic-changehunk with its justification or fix - the four "Verify carefully" resolutions with evidence (Role mapping; DDS stub real-path; logger; filter API)
- the ArcGIS include-style decision (prefix vs bare) and the reason
- the Esri dictionary-processor equivalence evidence
- exact validation commands and results (targeted build + the
--group5docker run + ctest) - remaining blockers or risks
Summary
Write a MIGRATION_SUMMARY_ARCGIS300_SYMBOLOGY.md (same style/convention as
MIGRATION_SUMMARY_Z_AND_PROXIES.md) documenting: the scope audited, the migration-only
pattern classes found, the four verify-carefully resolutions, the ArcGIS 300 include-style
reconciliation, the validation commands/results, and the remaining blockers. Place it at the
migrated-tree root (qt6-after/qt6-migrated-legatus/) and commit it with the work.