-
-
Notifications
You must be signed in to change notification settings - Fork 38
fix 3D live tracking #383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix 3D live tracking #383
Conversation
Reviewer's GuideRefactors the exaggerated elevation layer into a typed BaseElevationLayer subclass, ensures the ArcGIS elevation sampler loads before use, guards against undefined view centers in the watcher, and gates rendering of the 3D tracking component on the ArcGIS API load state. Sequence diagram for 3D tracking gating on ArcGIS API readinesssequenceDiagram
actor User
participant Map3dElement
participant Store
participant ArcgisApi
participant ArcgisView
participant Tracking3dElement
User->>Map3dElement: load_component()
Map3dElement->>Store: setApiLoading(true)
Store-->>Map3dElement: stateChanged(loadingApi=true)
Map3dElement->>Map3dElement: apiLoaded = false
ArcgisApi-->>ArcgisView: initialize_view_and_layers()
ArcgisView-->>Store: setApiLoading(false)
Store-->>Map3dElement: stateChanged(loadingApi=false)
Map3dElement->>Map3dElement: apiLoaded = true
Map3dElement->>Map3dElement: render()
Map3dElement->>Tracking3dElement: render_tracking3d_element(layer,gndLayer,tracks,currentTrackId,timeSec,multiplier)
activate Tracking3dElement
Tracking3dElement-->>User: display_3d_live_tracking
deactivate Tracking3dElement
Updated class diagram for Map3dElement and ExaggeratedElevationLayerclassDiagram
class Map3dElement {
- GraphicsLayer graphicsLayer
- GraphicsLayer gndGraphicsLayer
- boolean apiLoaded
- ExaggeratedElevationLayer elevationLayer
- number multiplier
+ stateChanged(state RootState) void
+ connectedCallback() void
+ firstUpdated() void
+ render() unknown
}
class BaseElevationLayer {
+ load() Promise~void~
+ fetchTile(level number,row number,col number,options BaseElevationLayerFetchTileOptions) ElevationTileData
+ addResolvingPromise(promise Promise~void~) void
}
class ElevationLayer {
+ url string
+ load() Promise~void~
+ fetchTile(level number,row number,col number,options BaseElevationLayerFetchTileOptions) ElevationTileData
}
class ExaggeratedElevationLayer {
+ number multiplier
+ ElevationLayer _elevation
+ ExaggeratedElevationLayer(multiplier number,properties BaseElevationLayerProperties)
+ load() Promise~void~
+ fetchTile(level number,row number,col number,options BaseElevationLayerFetchTileOptions) ElevationTileData
}
Map3dElement --> ExaggeratedElevationLayer : uses_as_elevationLayer
ExaggeratedElevationLayer --|> BaseElevationLayer : extends
ExaggeratedElevationLayer --> ElevationLayer : wraps_for_sampling
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughReplaces the elevation-layer factory with a decorated ExaggeratedElevationLayer class, adds an apiLoaded state flag to gate 3D rendering, and updates lifecycle and render logic to create/swap the exaggerated elevation layer and tolerate undefined location Points. Changes
Estimated code review effortπ― 3 (Moderate) | β±οΈ ~25 minutes Poem
Pre-merge checks and finishing touchesβ Passed checks (3 passed)
β¨ Finishing touches
π§ͺ Generate unit tests (beta)
π Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro π Files selected for processing (1)
𧰠Additional context used𧬠Code graph analysis (1)apps/fxc-front/src/app/components/3d/map3d-element.ts (1)
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
π Additional comments (7)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - I've found 2 issues, and left some high level feedback:
- In
ExaggeratedElevationLayer.fetchTile, returning an empty object when_elevationis undefined can hide loading issues and produce invalid data; consider awaiting the layer load or throwing/logging an explicit error instead of returning a dummy tile. - The
ExaggeratedElevationLayerconstructor always overridesmultiplierfrom its first parameter and ignores anymultiplierthat might be passed viaproperties; if this class is ever instantiated by the ArcGIS runtime or via JSON, you may want to derivemultiplierfrompropertiesto avoid surprising behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `ExaggeratedElevationLayer.fetchTile`, returning an empty object when `_elevation` is undefined can hide loading issues and produce invalid data; consider awaiting the layer load or throwing/logging an explicit error instead of returning a dummy tile.
- The `ExaggeratedElevationLayer` constructor always overrides `multiplier` from its first parameter and ignores any `multiplier` that might be passed via `properties`; if this class is ever instantiated by the ArcGIS runtime or via JSON, you may want to derive `multiplier` from `properties` to avoid surprising behavior.
## Individual Comments
### Comment 1
<location> `apps/fxc-front/src/app/components/3d/map3d-element.ts:472-478` </location>
<code_context>
- const layer = new Layer();
- layer.multiplier = multiplier;
- return layer;
+ async fetchTile(
+ level: number,
+ row: number,
+ col: number,
+ options?: __esri.BaseElevationLayerFetchTileOptions,
+ ): Promise<__esri.ElevationTileData> {
+ if (!this._elevation) {
+ return {} as any;
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid returning an empty object when `_elevation` is not yet initialized.
Casting `{}` to `any` when `_elevation` is undefined breaks the contract of returning a valid `ElevationTileData` and can cause subtle runtime errors if `fetchTile` is called before `load` completes. Instead, either wait for initialization (e.g., `if (!this._elevation) await this.load();`) or throw a clear error so callers never receive an invalid tile payload.
</issue_to_address>
### Comment 2
<location> `apps/fxc-front/src/app/components/3d/map3d-element.ts:458-460` </location>
<code_context>
- return data;
- });
- },
+ constructor(multiplier: number, properties?: __esri.BaseElevationLayerProperties | undefined) {
+ super(properties);
+ this.multiplier = multiplier;
+ }
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Custom constructor signature may diverge from the standard ArcGIS layer construction pattern.
The current signature `(multiplier: number, properties?)` only forwards `properties` to `super` and relies on positional args, which diverges from the usual `new Layer({ ...properties })` pattern. This risks misuse if the layer is ever instantiated via standard ArcGIS mechanisms or elsewhere with `new ExaggeratedElevationLayer({ multiplier: 2 })`, where `multiplier` would be ignored.
Consider accepting a single `properties` object that includes `multiplier`:
```ts
constructor(properties?: __esri.BaseElevationLayerProperties & { multiplier?: number }) {
super(properties);
if (properties?.multiplier != null) {
this.multiplier = properties.multiplier;
}
}
```
and update call sites to `new ExaggeratedElevationLayer({ multiplier: this.multiplier })` to match the standard pattern.
Suggested implementation:
```typescript
constructor(
properties?: __esri.BaseElevationLayerProperties & { multiplier?: number },
) {
super(properties);
if (properties?.multiplier != null) {
this.multiplier = properties.multiplier;
}
}
```
You will also need to update all instantiations of `ExaggeratedElevationLayer` in this file (and elsewhere in the codebase) to follow the standard ArcGIS pattern. For example, change:
```ts
new ExaggeratedElevationLayer(this.multiplier)
```
to:
```ts
new ExaggeratedElevationLayer({ multiplier: this.multiplier })
```
and if there were existing properties:
```ts
new ExaggeratedElevationLayer(this.multiplier, { id: 'exaggerated-elev' })
```
to:
```ts
new ExaggeratedElevationLayer({ id: 'exaggerated-elev', multiplier: this.multiplier })
```
Search for `new ExaggeratedElevationLayer(` and adjust each call accordingly so the first (and only) argument is a single properties object that may include `multiplier`.
</issue_to_address>Help me be more useful! Please click π or π on each comment and I'll use the feedback to improve your reviews.
| async fetchTile( | ||
| level: number, | ||
| row: number, | ||
| col: number, | ||
| options?: __esri.BaseElevationLayerFetchTileOptions, | ||
| ): Promise<__esri.ElevationTileData> { | ||
| if (!this._elevation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Avoid returning an empty object when _elevation is not yet initialized.
Casting {} to any when _elevation is undefined breaks the contract of returning a valid ElevationTileData and can cause subtle runtime errors if fetchTile is called before load completes. Instead, either wait for initialization (e.g., if (!this._elevation) await this.load();) or throw a clear error so callers never receive an invalid tile payload.
Deploying flyxc with Β
|
| Latest commit: |
752b85c
|
| Status: | Β β Β Deploy successful! |
| Preview URL: | https://abe85254.flyxc.pages.dev |
| Branch Preview URL: | https://vicb-exa.flyxc.pages.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
π§Ή Nitpick comments (1)
apps/fxc-front/src/app/components/3d/map3d-element.ts (1)
451-488: Consider improving the fallback infetchTilewhen_elevationis undefined.The class implementation is well-structured with proper ArcGIS decorators. However, returning
{} as any(lines 478-479) when_elevationis undefined could cause subtle issues downstream iffetchTileis called beforeload()completes.Consider returning a more explicit empty tile structure or throwing an error to make the failure mode clearer:
π Suggested alternative
async fetchTile( level: number, row: number, col: number, options?: __esri.BaseElevationLayerFetchTileOptions, ): Promise<__esri.ElevationTileData> { if (!this._elevation) { - return {} as any; + throw new Error('ExaggeratedElevationLayer: fetchTile called before load completed'); } const data = await this._elevation.fetchTile(level, row, col, options);Alternatively, if the ArcGIS framework expects a silent fallback, the current approach is acceptable given the
apiLoadedgating now prevents premature usage.
π Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (1)
apps/fxc-front/src/app/components/3d/map3d-element.ts
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build (22.x)
- GitHub Check: Analyze (javascript)
- GitHub Check: Sourcery review
- GitHub Check: Cloudflare Pages
π Additional comments (8)
apps/fxc-front/src/app/components/3d/map3d-element.ts (8)
10-10: LGTM!The import is correctly added to support the ArcGIS decorators used in the new
ExaggeratedElevationLayerclass.
62-63: LGTM!The new
apiLoadedstate property is properly declared and will correctly trigger re-renders when the API loading status changes.
84-84: LGTM!The boolean inversion correctly maps the loading state to readiness:
apiLoadedbecomestrueonly whenloadingApiisfalse.
121-128: LGTM!The elevation layer replacement logic correctly removes the old layer before adding the new one with the updated multiplier.
144-147: LGTM!Resetting
apiLoadedtofalseinconnectedCallbackensures the component starts in a safe state when reconnecting, and correctly triggers the API loading flow.
158-159: LGTM!Correctly uses the new
ExaggeratedElevationLayerclass for initial elevation layer creation.
253-260: LGTM!Good defensive programming. The optional
Pointparameter and null check prevent potential runtime errors whenview.centeris undefined during initialization or transitions.
416-423: Core fix: correctly gates 3D element rendering until API is ready.This addresses the PR objective by ensuring
tracking3d-element(which receives theelevationSampler) is not rendered untilapiLoadedis true, preventing premature sampler usage.
Do not use the sampler before it is ready
Do not use the sampler before it is ready
Summary by Sourcery
Ensure 3D map live tracking only starts once the ArcGIS API and elevation data are fully initialized.
Bug Fixes:
Enhancements:
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
βοΈ Tip: You can customize this high-level summary in your review settings.