05_MigrationImplementation_ProposalsA1 Geometry Processor Triage Workflow Proposal

A1 Geometry Processor Triage Workflow Proposal

Document Status

This is a reformatted reference note based on New Triage Workflow.md.

Role in the Knowledge Base

This note is not a manual-derived script overview. It is a future implementation proposal for the PythonNet3 migration of A1-style geometry processing.

Use this note when reverse-engineering or redesigning the internal geometry-processing engine behind A1a_Plot_Survey_Data_From_Point_Data_File and A1b_Plot_Survey_Data_From_Drawing_Selection.

Source Priority

Source TypeStatus
HAPI User ManualDefines user-facing script purpose and business rules.
This proposalDefines a proposed internal triage architecture.
FeatureCatalogue.jsonRemains the source of truth for feature routing and symbol configuration.

Key Ideas

  • Global pre-sort by Point Number.
  • Four processing channels: 1POINT, 2POINT, LINEAR, and POLYGON.
  • First triage and second triage.
  • Transfer rules between processing channels.
  • POLYGON grouping, chopping, clustering, subgroup triage, and reconstruction.
  • Supplementary suffix handling for KX...G and FX...G.

This document consolidates the fully amended workflow for A1_GeometryProcessor.py. It supersedes v4 in its entirety. All changes from the v4 review cycle are incorporated.

This proposal defines:

  • Global pre-processing rules (G0–G4)
  • Channel responsibilities
  • First Triage and Second Triage
  • Transfer-in and transfer-out rules for each channel
  • POLYGON grouping, chopping, clustering, subgroup triage, and reconstruction rules
  • Updated worked examples reflecting the new architecture

Global Rules

G0. Global Pre-Sort

Immediately after A1_GeometryProcessor.py receives the SurveyRecord list from the upstream StandardDataPool, and before any channel triage begins, the entire record list must be sorted by PointNumber ascending.

This sorted sequence is the single canonical ordering for all subsequent channel workflows. No channel is permitted to re-sort its own queue; all grouping, chopping, pairing, and clustering must operate on this pre-sorted sequence.

G1. Parsed Feature-Code Source

No new data type for parsed feature-code components shall be created. All parsed values — BaseFeatureCode, NumericSuffix, SuffixKind, SuffixValue, and SupplementarySuffix — must be read directly from the SurveyRecord instance produced by the canonical BuildSurveyRecordFromSeedParsePointCodeResolveParsedPointCode pipeline.

SuffixKind is determined from NumericSuffix as follows:

NumericSuffix valueSuffixKind
None / emptyNONE
1–9 (1-digit)SIZING_1DIGIT
01–99 (2-digit, zero-padded)CLUSTERING_2DIGIT

G2. Decision Sources

Workflow decisions must be based exclusively on:

  • FeatureType
  • SymbolGroupingLengths
  • PointSymbolUseBlkRef
  • MultiPolySymbolUseBlkRef
  • FeatureLineStyleName
  • SuffixKind, SuffixValue, SupplementarySuffix (from SurveyRecord)

The following catalogue fields must not be used for decision-making:

  • PointSymbolParameter
  • MultiPolySymbolParameter

G3. Rotation Conventions

  • PointSymbol: insertion at symbol centre; rotation origin = north = 0°; clockwise positive.
  • MultiPolySymbol: insertion at mid-point of the left width side; rotation origin = east = 0°; clockwise positive.

G4. Arbitrary Dimension

When an arbitrary rectangle or square construction is required:

Width = ArbitraryDimension * CurrentDrawingScale
Length = ArbitraryDimension * CurrentDrawingScale

(ArbitraryDimension sourced from DefaultSymbolArbitraryDimension in GlobalConfiguration.)


Channel Overview

There are four channels:

  1. 1POINT — single-point PointSymbol insertion only
  2. 2POINT — all exact two-point reconstruction (MultiPoly, PointSymbol fallback, FeatureLine fallback)
  3. LINEAR — path-based line construction and supplementary-suffix special handling
  4. POLYGON — all 3-point-or-above polygon-like grouping, chopping, clustering, subgroup triage, and reconstruction

The overall workflow has two triage stages:

  • First Triage: collect records into their initial channel queues.
  • Second Triage: apply channel-specific transfer rules based on suffix and behaviour.

Channel Responsibility Summary

ChannelHandlesTransfer-InTransfer-Out
1POINTSingle-point PointSymbol placementNative 1POINT; KX...G clone from LINEAR; B-POLY-1P PointSymbol subgroup from POLYGONSIZING_1DIGIT == 2 → 2POINT; SIZING_1DIGIT >= 3 → POLYGON; CLUSTERING_2DIGIT → POLYGON
2POINTAll exact two-point reconstructionNative 2POINT; sizing-2 transfer from 1POINT; all 2-point subgroups from POLYGON; FX...G clone from LINEARNone
LINEARPath-based line geometryNative LINEARKX...G → 1POINT; FX...G → 2POINT
POLYGON3-point-or-above grouping, chopping, clustering, reconstructionNative POLYGON; sizing-3+ transfer from 1POINT; clustering transfer from 1POINTB-POLY-1P PointSymbol → 1POINT; all 2-point subgroups (B-POLY-2P any rule) → 2POINT

1POINT Channel

Responsibility

The 1POINT Channel is responsible only for single-point PointSymbol block insertion. It does not perform:

  • Polygon fitting
  • Pair geometry fitting
  • Best-fit rectangle solving
  • Clustering reconstruction

Transfer-In

The 1POINT Channel receives:

  1. Native FeatureType == 1POINT records during First Triage.
  2. KX...G clone records transferred from the LINEAR Channel.
  3. B-POLY-1P PointSymbol subgroups transferred from the POLYGON Channel.

Transfer-Out (Second Triage)

Suffix conditionDestination
SuffixKind == NONE or SIZING_1DIGIT == 1Stay in 1POINT
SIZING_1DIGIT == 2Transfer to 2POINT
SIZING_1DIGIT >= 3Transfer to POLYGON
CLUSTERING_2DIGIT (any)Transfer to POLYGON

Explicit example — EM:

CodeDestination
EMStay in 1POINT
EM1Stay in 1POINT
EM2Transfer to 2POINT
EM3EM9Transfer to POLYGON
EM01EM99Transfer to POLYGON

What 1POINT Channel Does

For every record or transfer-in subgroup:

  1. Use the survey point as insertion point.
  2. If PointSymbolAlignToKerb == true, attempt kerb alignment using harvested kerb geometry.
  3. Otherwise use existing ObjectRotation value, or default = 0.
  4. Insert PointSymbol block if PointSymbolUseBlkRef == true.
  5. Output BlkRefPackage only.

Output

  • BlkRefPackage only.

2POINT Channel

Responsibility

The 2POINT Channel is responsible for all exact two-point reconstruction, using the following mode hierarchy:

  1. MultiPolySymbol (when MultiPolySymbolUseBlkRef == true)
  2. PointSymbol midpoint fallback (when MultiPolySymbolUseBlkRef == false and PointSymbolUseBlkRef == true)
  3. FeatureLine fallback (when both block flags are false and FeatureLineStyleName exists)
  4. Warning — unresolved subgroup

Transfer-In

The 2POINT Channel receives:

  1. Native FeatureType == 2POINT records during First Triage.
  2. SIZING_1DIGIT == 2 transfer-in records from 1POINT Channel (e.g. EM2).
  3. All 2-point subgroups transferred from POLYGON Channel (B-POLY-2P any rule).
  4. FX...G clone records transferred from LINEAR Channel (gate pairs).

Transfer-Out

The 2POINT Channel does not transfer records out to other channels.

Second Triage Rules

Records are grouped by BaseFeatureCode before pairing. Native 2POINT records and transfer-in records are grouped separately by their BaseFeatureCode — they are never mixed across different base codes.

For native 2POINT records carrying a numeric suffix (e.g. EG01, GA2):

  • The record still stays in 2POINT.
  • The suffix is ignored for chopping logic.
  • A warning is logged.

2POINT Internal Grouping

After grouping by BaseFeatureCode:

  1. Use the globally pre-sorted sequence — do not re-sort.
  2. Chop strictly into consecutive pairs (every 2 records = one subgroup).
  3. If a remainder point exists, stop at the last complete pair and log a warning.

Internal Mode Selection

For each 2-point subgroup:

IF MultiPolySymbolUseBlkRef == true:
    → B-2P MultiPolySymbol Rule
ELSE IF PointSymbolUseBlkRef == true:
    → B-2P PointSymbol Fallback Rule
ELSE IF FeatureLineStyleName exists:
    → L-2P Linear Rule
ELSE:
    → Warning: unresolved subgroup

B-2P MultiPolySymbol Rule

  1. Use the two points as pair geometry.
  2. Insertion point = mid-point of the left width side (MultiPoly convention).
  3. ObjectLength = distance between point A and point B.
  4. ObjectWidth = ArbitraryDimension * CurrentDrawingScale.
  5. ObjectRotation = bearing A→B, east = 0°, clockwise positive (MultiPoly convention).
  6. Do not read MultiPolySymbolParameter dictionary.
  7. Only populate parameters that are present in the catalogue entry (e.g. BB, GV, TI, SLP, RB require ObjectLength, ObjectRotation only; ET, UB, TK require ObjectLength, ObjectWidth, ObjectRotation).
  8. Output BlkRefPackage.

B-2P PointSymbol Fallback Rule

When MultiPolySymbolUseBlkRef == false but PointSymbolUseBlkRef == true:

  1. Insertion point = midpoint between point A and point B.
  2. The pair's primary geometric contribution is orientation.
  3. ObjectRotation = bearing(A → B) − 90°, using PointSymbol convention (north = 0°, clockwise positive).
  4. If additional PointSymbol parameters exist in the catalogue, populate them only where present; if none, insert the block with rotation only.
  5. Output BlkRefPackage.

L-2P Linear Rule

When MultiPolySymbolUseBlkRef == false and FeatureLineStyleName exists:

  1. Connect point A to point B as a 2-point line.
  2. Apply FeatureLineStyleName.
  3. If annotation is enabled, add annotation using current workflow.
  4. Output LinearPackage.

Output

  • BlkRefPackage for B-2P MultiPolySymbol and B-2P PointSymbol Fallback.
  • LinearPackage for L-2P Linear.

LINEAR Channel

Responsibility

The LINEAR Channel is responsible only for path-based line construction and supplementary-suffix special handling. It does not perform polygon fitting or subgroup rectangle inference.

Transfer-In

The LINEAR Channel receives all native FeatureType == LINEAR records during First Triage.

Transfer-Out

ConditionDestination
KX record with SupplementarySuffix == "G"Clone → 1POINT
FX record with SupplementarySuffix == "G"Clone pair → 2POINT
All other LINEAR recordsStay in LINEAR

Second Triage Internal Rules

  1. Process SegmentTypeIndicator where applicable.
  2. Process SupplementarySuffix where applicable.
  3. Handle special transfer rules:
    • KX…G → 1POINT: Use copy.copy(F), set FeatureCode = "G". Push clone to 1POINT queue. Original KX record stays in LINEAR and continues to participate in the kerb line path.
    • FX…G → 2POINT: FX...G records always appear in pairs in the field (e.g. FX01G, FX01G). For each such pair, use copy.copy(F) on each record and set FeatureCode = "GA". Push the cloned pair to the 2POINT queue as a gate pair for reconstruction. The original FX geometry is split at the gate positions, forming gaps in the fence line; each sub-segment is output as an independent LinearPackage.
  4. All remaining ordinary LINEAR records stay in LINEAR and are built as path-based geometry.

What LINEAR Channel Does

  1. Build line path geometry from the globally pre-sorted ordered points.
  2. Respect linear feature style settings.
  3. Apply requested annotation / feature-flow labelling where applicable.
  4. Output LinearPackage.

Output

  • LinearPackage only for geometry built inside LINEAR.
  • Transfer queues to 1POINT and 2POINT only for KX...G and FX...G rules.

POLYGON Channel

Responsibility

The POLYGON Channel is responsible for all 3-point-or-above polygon-like grouping and shape inference. It handles:

  • Suffixless grouping using SymbolGroupingLengths
  • Sizing-number chopping
  • Clustering-number grouping
  • Subgroup internal triage
  • B-POLY reconstruction
  • L-POLY reconstruction
  • Transfer-out of B-POLY-1P PointSymbol subgroups to 1POINT
  • Transfer-out of all B-POLY-2P subgroups to 2POINT

The POLYGON Channel is also the destination for promoted 1POINT sizing and clustering cases (e.g. EM3, EM01).

Transfer-In

The POLYGON Channel receives:

  1. All native FeatureType == POLYGON records during First Triage.
  2. SIZING_1DIGIT >= 3 transfer-in from 1POINT Channel (e.g. EM3, EM5).
  3. CLUSTERING_2DIGIT transfer-in from 1POINT Channel (e.g. EM01, EM99).

Transfer-Out

RuleDestination
B-POLY-1P PointSymbol Rule→ 1POINT
All B-POLY-2P subgroups (any 2-point rule)→ 2POINT

All other subgroups remain in POLYGON for reconstruction.

First Triage

Retrieve all native FeatureType == POLYGON records.

Second Triage

Accept transfer-in records from 1POINT, then proceed to internal grouping.

At the entry point of POLYGON Channel (before chopping), all records in the channel queue — both native POLYGON and transfer-in records — are grouped by BaseFeatureCode. Records with different BaseFeatureCodes are never mixed.

POLYGON Internal Grouping

Step P1. Group by Feature Family

Group all records in the POLYGON queue by BaseFeatureCode.

Step P2. Use Pre-Sorted Sequence

Within each feature group, use the globally pre-sorted sequence. Do not re-sort.

Step P3. Determine Chopping Mode

There are three chopping modes:

A. Suffixless POLYGON chopping

Subgroup size is given by SymbolGroupingLengths. Examples:

  • ICSymbolGroupingLengths = 3
  • UBSymbolGroupingLengths = 2
  • MTSymbolGroupingLengths = 1

B. Sizing-number chopping

For 1-digit suffix records, use the suffix digit directly as group size. Examples:

  • IC2 → chop by 2
  • EM3 → chop by 3

C. Clustering-number grouping

For 2-digit suffix records, do not chop by size. Instead:

  • Group by BaseFeatureCode + ClusteringNumber
  • Each cluster becomes one subgroup
  • Subgroup point count may be any size

Examples: IC01, FB14, EM99.


POLYGON Chopping Rules

P-Rule 1. Suffixless — Complete-Groups Rule

For suffixless POLYGON groups:

  • Only complete groups of size SymbolGroupingLengths are processed.
  • Any final incomplete remainder is dropped with a warning log.

Example: IC with count 5, group length 3 → process first 3 points as one subgroup; drop remaining 2 with warning.

P-Rule 2. Sizing — Complete-Groups Rule

For sizing-number chopping:

  • Only complete groups are processed.
  • Any final incomplete remainder is dropped with a warning log.

Example: EM3 with count 7 → process first 6 as two subgroups of 3; drop final 1 with warning.

P-Rule 3. Suffixless — Gap-Based Subgroup Splitting (updated)

When chopping a suffixless feature group, the chopper must detect point number gaps within the sequence. A gap is defined as a difference of more than 1 between two consecutive point numbers in the sorted sequence.

Rule: When a gap is detected, the current batch is closed immediately and treated as one subgroup candidate.

After closing a batch at a gap boundary:

  • If batch count == SymbolGroupingLengths: standard subgroup.
  • If batch count == 4 and SymbolGroupingLengths == 3: apply 4-point exception — treat the 4 records as one 4-point subgroup.
  • If batch count == SymbolGroupingLengths - 1 (i.e. one short): log warning; drop the incomplete batch.
  • Any other count: log warning; drop the batch.

The remaining records after the gap start a new batch and the same logic applies.

Examples:

FB suffixless, SymbolGroupingLengths = 3
Input point numbers: 11, 12, 13, 14, 16, 17, 18, 19, 20, 21

Gap detected after 14 (gap = 2).
Batch 1 = [11, 12, 13, 14] → count 4, GroupLen 3 → 4-point exception → subgroup (11-14).
Remaining: [16, 17, 18, 19, 20, 21]

Gap detected after 18? No gap between 16-21 (all consecutive).
Chop by 3: subgroup (16-18), subgroup (19-21).

Result: 3 subgroups: (11-14), (16-18), (19-21).
FB suffixless, SymbolGroupingLengths = 3
Input: 11, 12, 13, 16, 17, 18, 19, 20, 21

Gap detected after 13 (gap = 3).
Batch 1 = [11, 12, 13] → count 3, GroupLen 3 → standard subgroup (11-13).
Remaining: [16, 17, 18, 19, 20, 21]
Chop by 3: subgroup (16-18), subgroup (19-21).

Result: 3 subgroups: (11-13), (16-18), (19-21).

POLYGON Internal Triage by Subgroup Type

After chopping/clustering, each subgroup is classified by point count and catalogue capability.

A. NumberOfPoints == 1

PointSymbolUseBlkRefMultiPolySymbolUseBlkRefRuleAction
truetrueB-POLY-1P PointSymbol RuleTransfer-out → 1POINT
falsetrueB-POLY-1P MultiPolySymbol RuleStay in POLYGON
truefalseB-POLY-1P PointSymbol RuleTransfer-out → 1POINT
falsefalseL-POLY-1P RuleStay in POLYGON

B. NumberOfPoints == 2

All 2-point subgroups transfer out to 2POINT regardless of block flags.

PointSymbolUseBlkRefMultiPolySymbolUseBlkRefRule NameAction
truetrueB-POLY-2P MultiPolySymbol RuleTransfer-out → 2POINT
falsetrueB-POLY-2P MultiPolySymbol RuleTransfer-out → 2POINT
truefalseB-POLY-2P PointSymbol RuleTransfer-out → 2POINT
falsefalseL-POLY-2P RuleStay in POLYGON (isClosed = false)

C. NumberOfPoints >= 3

MultiPolySymbolUseBlkRefPointSymbolUseBlkRefRuleAction
trueB-POLY-3+ MultiPolySymbol RuleStay in POLYGON
falsetrueB-POLY-3+ PointSymbol RuleStay in POLYGON
falsefalseL-POLY-3+ RuleStay in POLYGON

D. Clustering Subgroup (any count)

Clustering subgroups are never transferred. They are always processed inside POLYGON.

ConditionRuleNote
MultiPolySymbolUseBlkRef == trueWarning onlyIrregular MultiPoly mode not defined; log warning, do not attempt reconstruction.
PointSymbolUseBlkRef == true (only)B-POLY-Cluster PointSymbol RuleStay in POLYGON (see B-POLY-3+ PointSymbol rule below).
Both false, FeatureLineStyleName existsL-POLY-Cluster RuleStay in POLYGON; connect all points in order.
Both false, no line styleWarning onlyUnresolved cluster; log warning.

Special case — Clustering subgroup with count == 2: Treat as a standard 2-point polygon with isClosed = false. Apply L-POLY-2P rule. No transfer to 2POINT. The user has explicitly accepted that a 2-point cluster is a degenerate polygon (a line).


POLYGON Reconstruction Rules

B-POLY-1P PointSymbol Rule

Transfer-out to 1POINT. Reconstruction handled in 1POINT Channel.

B-POLY-1P MultiPolySymbol Rule

For a subgroup with only 1 point but requiring a MultiPoly block:

  1. Construct an arbitrary square centred at the survey point.
  2. length = width = ArbitraryDimension * CurrentDrawingScale
  3. Insertion point = mid-point of the left width side (MultiPoly convention).
  4. ObjectLength = square side length.
  5. ObjectRotation = 0° (square; no directional information from a single point), using MultiPoly convention (east = 0°, clockwise).
  6. Output BlkRefPackage.

B-POLY-2P MultiPolySymbol Rule (transfer-out)

Transfer-out to 2POINT. Reconstruction handled in 2POINT Channel under B-2P MultiPolySymbol Rule.

B-POLY-2P PointSymbol Rule (transfer-out)

Transfer-out to 2POINT. Reconstruction handled in 2POINT Channel under B-2P PointSymbol Fallback Rule.

L-POLY-2P Rule

For a 2-point subgroup where both block flags are false and a FeatureLineStyleName exists:

  1. Connect the 2 points as a line segment.
  2. isClosed = false.
  3. Apply FeatureLineStyleName.
  4. Output LinearPackage.

B-POLY-3+ MultiPolySymbol Rule

For a subgroup of 3 or more points using a MultiPoly block:

  1. Compute best-fit rectangle from all subgroup points.
  2. Insertion point = mid-point of the left width side (rectangle).
  3. ObjectLength = rectangle length.
  4. ObjectWidth = rectangle width.
  5. ObjectRotation = long-axis orientation, MultiPoly convention (east = 0°, clockwise).
  6. Output BlkRefPackage.

B-POLY-3+ PointSymbol Rule

For a subgroup of 3 or more points where no MultiPoly block exists but a PointSymbol block is available:

  1. Compute best-fit rectangle from subgroup points.
  2. Insertion point = geometric centre of the rectangle.
  3. ObjectRotation = long-axis orientation, PointSymbol convention (north = 0°, clockwise).
  4. Do not rely on SymbolParameter dictionaries.
  5. Output BlkRefPackage.

L-POLY-3+ Rule

For a subgroup of 3 or more points where no block is available:

  1. Connect all points in order.
  2. isClosed = determined by current source workflow.
  3. Apply FeatureLineStyleName (annotation-style polygon if enabled).
  4. Output LinearPackage.

L-POLY-Cluster Rule

For a clustering-number subgroup where no block is available:

  1. Use all cluster points as vertices in point order.
  2. Connect them; isClosed = determined by source workflow.
  3. Apply FeatureLineStyleName where available.
  4. Output LinearPackage.

Worked Examples (Updated for v5)

Example 1 — MT (suffixless, POLYGON, PointSymbol, GroupLen 1)

  • Native POLYGON
  • Suffixless, SymbolGroupingLengths = 1
  • Chopped into 1-point subgroups
  • PointSymbolUseBlkRef == true → Transfer-out to 1POINT under B-POLY-1P PointSymbol Rule
  • Final reconstruction in 1POINT: single-point block insertion

Example 2 — MT2 (sizing-2, POLYGON, MultiPolySymbol)

  • Native POLYGON
  • Sizing suffix 2
  • Chopped into 2-point subgroups
  • MultiPolySymbolUseBlkRef == true → Transfer-out to 2POINT under B-POLY-2P MultiPolySymbol Rule
  • Final reconstruction in 2POINT: B-2P MultiPolySymbol Rule

Example 3 — EM2 (1POINT sizing-2 → 2POINT)

  • Native 1POINT
  • Sizing suffix 2
  • Second Triage in 1POINT: SIZING_1DIGIT == 2 → Transfer-out to 2POINT
  • Grouped by BaseFeatureCode = EM in 2POINT
  • Chopped into 2-point subgroups
  • PointSymbolUseBlkRef == true, MultiPolySymbolUseBlkRef == falseB-2P PointSymbol Fallback Rule
  • Insertion at midpoint; ObjectRotation = bearing(A→B) − 90°

Example 4 — UB (suffixless, POLYGON, MultiPolySymbol, GroupLen 2)

  • Native POLYGON
  • Suffixless, SymbolGroupingLengths = 2
  • Chopped into 2-point subgroups
  • MultiPolySymbolUseBlkRef == true → Transfer-out to 2POINT under B-POLY-2P MultiPolySymbol Rule
  • Final reconstruction in 2POINT: B-2P MultiPolySymbol Rule

Example 5 — IC (suffixless, POLYGON, L-POLY, GroupLen 3)

  • Native POLYGON
  • Suffixless, SymbolGroupingLengths = 3
  • Chopped into 3-point subgroups
  • PointSymbolUseBlkRef == false, MultiPolySymbolUseBlkRef == false, FeatureLineStyleName exists
  • → L-POLY-3+ Rule; stays in POLYGON
  • Output LinearPackage (annotation-style polygon)

Example 6 — IC01 (clustering, POLYGON, L-POLY-Cluster)

  • Native POLYGON
  • Clustering suffix 01
  • No sizing chop; all IC01 records form one subgroup
  • Both block flags false → L-POLY-Cluster Rule; stays in POLYGON
  • Output LinearPackage (open or closed per source workflow)
  • Special case: if the cluster contains only 2 points → isClosed = false

Example 7 — GA (native 2POINT, FeatureLine fallback)

  • Native 2POINT
  • PointSymbolUseBlkRef == false, MultiPolySymbolUseBlkRef == false, FeatureLineStyleName = "GA Gate" exists
  • Stays in 2POINT; no transfer
  • Reconstruction: L-2P Linear Rule
  • Output LinearPackage

Example 8 — GV (native 2POINT, MultiPolySymbol)

  • Native 2POINT
  • MultiPolySymbolUseBlkRef == true
  • Stays in 2POINT
  • Reconstruction: B-2P MultiPolySymbol Rule
  • Insertion at left-side reference; ObjectLength from pair geometry; ObjectRotation = east 0°, clockwise

Example 9 — FB suffixless (gap-based split, 4-point exception)

  • Native POLYGON, SymbolGroupingLengths = 3
  • Input point numbers: 11, 12, 13, 14, 16, 17, 18, 19, 20, 21
  • Gap detected after 14 → batch [11,12,13,14] → count 4, GroupLen 3 → 4-point exception → subgroup (11-14)
  • Remaining [16,17,18,19,20,21] no gap → chop by 3 → subgroups (16-18), (19-21)
  • Result: 3 subgroups; each processed under L-POLY or B-POLY rule per block availability

Example 10 — KX…G (LINEAR → 1POINT grating clone)

  • Native LINEAR feature KX with SupplementarySuffix = "G"
  • Clone created: FeatureCode changed to G; clone pushed to 1POINT queue
  • G has PointSymbolUseBlkRef == true and PointSymbolAlignToKerb == true
  • 1POINT reconstruction: PointSymbol with kerb alignment
  • Original KX record remains in LINEAR; continues to participate in the kerb line path

Example 11 — FX…G (LINEAR → 2POINT gate pair clone)

  • Native LINEAR feature FX with SupplementarySuffix = "G", always appearing as a pair (e.g. FX01G, FX01G)
  • Two clones created: each FeatureCode changed to GA; clone pair pushed to 2POINT queue
  • GA has PointSymbolUseBlkRef == false, MultiPolySymbolUseBlkRef == false, FeatureLineStyleName = "GA Gate"
  • 2POINT reconstruction under L-2P Linear Rule: gate line drawn between the two clone points
  • Original FX geometry split at gate positions; each sub-segment output as independent LinearPackage (fence line with gap)

1. Parse Log

P1 Parse PointName=<n> FCode=<IC01>
  → BaseCode=IC NumericSuffix=01 SuffixKind=CLUSTERING_2DIGIT SupplementarySuffix=None

2. First Triage Log

P2 Triage-1 FCode=EM PointName=123 → 1POINT (Base FeatureType=1POINT)
P2 Triage-1 FCode=GA PointName=888 → 2POINT (Base FeatureType=2POINT)
P2 Triage-1 FCode=IC PointName=222 → POLYGON (Base FeatureType=POLYGON)

3. Second Triage Log

P3 Triage-2 FCode=EM2 PointName=301 → Transfer 1POINT to 2POINT [Sizing-2 Rule]
P3 Triage-2 FCode=EM3 PointName=401 → Transfer 1POINT to POLYGON [Sizing-3 Rule]
P3 Triage-2 FCode=EG01 PointName=501 → Stay in 2POINT [Suffix ignored in 2POINT Channel] WARNING

4. POLYGON Chop Log

P3 POLY-Chop FCode=IC suffixless GroupLen=3 Count=9 → SubGroups=3
P3 POLY-Chop FCode=IC suffixless GroupLen=3 Count=5 → CompleteGroups=1, Remainder=2 STOP, remainder dropped
P3 POLY-Chop FCode=FB suffixless GroupLen=3, gap detected after pt14 → batch [11-14] count=4 → 4-point exception
P3 POLY-Chop FCode=IC01 clustering key=01 Count=6 → SubGroupCount=1

5. Subgroup Triage & Reconstruction Log

P3 POLY-Subgroup FCode=MT subgroup1 pts=1 → Transfer to 1POINT [B-POLY-1P PointSymbol]
P3 POLY-Subgroup FCode=MT2 subgroup1 pts=2 → Transfer to 2POINT [B-POLY-2P MultiPolySymbol]
P3 POLY-Subgroup FCode=EM2 subgroup1 pts=2 → Transfer to 2POINT [B-POLY-2P PointSymbol]
P3 POLY-Subgroup FCode=IC subgroup1 pts=3 → Stay POLYGON [L-POLY-3+]
P3 POLY-Recon FCode=EM3 subgroup1 PointSymbol centre=(E,N) rot=...°

Final Design Summary

  1. The entire SurveyRecord list is sorted globally by PointNumber ascending before any triage begins. No channel re-sorts.
  2. Parsed feature-code components are read from SurveyRecord fields; no new data type is created.
  3. 1POINT Channel handles single-point PointSymbol insertion only. SIZING_1DIGIT == 2 transfers to 2POINT.
  4. 2POINT Channel handles all exact two-point reconstruction: MultiPolySymbol → PointSymbol fallback → FeatureLine fallback → unresolved warning.
  5. LINEAR Channel handles path-based geometry and supplementary-suffix special transfers (KX...G → 1POINT; FX...G pair → 2POINT).
  6. POLYGON Channel handles sizing (3+), clustering, subgroup inference, 3+-point reconstruction. All 2-point subgroups transfer out to 2POINT. 1-point PointSymbol subgroups transfer out to 1POINT.
  7. Clustering subgroups with count == 2 stay in POLYGON under L-POLY-2P rule with isClosed = false.
  8. Gap-based splitting (P-Rule 3) governs suffixless chopping when point number sequences are non-consecutive.
  9. Native 2POINT suffixes do not affect chopping; they only trigger warnings.
  10. SymbolParameter dictionaries are not used for decision-making.
Built with LogoFlowershow