Skip to content

feat(#35): ✨ Change to offline rendering #36

Merged
merged 8 commits into from
Oct 20, 2025

Conversation

kleinc
Copy link
Member

@kleinc kleinc commented Oct 20, 2025

Add geoJSON file to replace the online OSM. Use this for offline rendering.

Issue number

Closes #35

Description

Change to offline rendering with a geoJSON map. Map downloaded from: https://www.naturalearthdata.com/downloads/50m-cultural-vectors/

Testing steps

  • Start the application. You will see the new globe
  • Try to move above the horizon to see that both the globe and countries disappear. Render it back again
  • Move around the scene to check if everything looks clean

Screenshots

Skjermbilde 2025-10-20 kl  10 14 13

Summary by CodeRabbit

  • New Features

    • Country borders displayed on the globe and now toggle visibility in sync with the globe; loaded at startup with error handling.
  • UI/Visualization

    • Globe base color updated to a semi‑transparent light blue.
    • Default map imagery layer removed for a cleaner visualization.
  • Enhancement

    • Default camera/start view updated for a different initial perspective.
  • Tests

    • Added end-to-end rendering test to exercise globe rendering and basic interactions.

Add geoJSON file to replace the online OSM. Use this for offline rendering.
@kleinc kleinc self-assigned this Oct 20, 2025
@kleinc kleinc linked an issue Oct 20, 2025 that may be closed by this pull request
@coderabbit
Copy link

coderabbit bot commented Oct 20, 2025

Walkthrough

Adds offline globe rendering with a semi‑transparent base color, a loader to add GeoJSON country borders to the Cesium viewer (stored as viewer._countryBorders), calls that loader during init, syncs _countryBorders.show with globe visibility toggles, tweaks Potree initial view, and adds a simple Cypress render interaction test.

Changes

Cohort / File(s) Summary
Cesium viewer & offline globe
src/cesiumViewer.js
Sets imageryProvider: false, sets globe.baseColor to #D6EBF2 @ alpha 0.5, and adds export async function loadCountryBorders(viewer) which loads /data/geo/world_simplified.geojson, styles it, adds it to viewer.dataSources, assigns viewer._countryBorders, and returns the datasource.
Initialization integration
src/main.js
Imports loadCountryBorders and awaits loadCountryBorders(window.cesiumViewer) during init (after creating the Cesium viewer, before creating the Potree viewer); errors are caught and logged to console.error.
Visibility synchronization
src/cameraSync.js
Extends globe/skyAtmosphere visibility toggles to also set cesiumViewer._countryBorders.show when viewer._countryBorders exists, using the same showGlobe value.
Potree view update
src/potreeViewer.js
Adjusts the initial camera position and target passed to viewer.scene.view.setView; no other logic changes.
End-to-end test
cypress/e2e/globeRendering.cy.js
Adds a new Cypress test that visits the app and performs repeated clicks on the Potree canvas (#potree_render_area canvas[tabindex="2222"]) to trigger globe rendering/interactions.

Sequence Diagram(s)

sequenceDiagram
    participant Main as main.js
    participant CV as cesiumViewer.js
    participant Cesium as Cesium Viewer
    participant Geo as /data/geo/world_simplified.geojson

    Main->>CV: createCesiumViewer()
    Main->>CV: await loadCountryBorders(window.cesiumViewer)
    activate CV
    CV->>Geo: fetch GeoJSON
    Geo-->>CV: return GeoJSON
    CV->>Cesium: dataSources.add(GeoJsonDataSource) & apply style
    CV->>Cesium: viewer._countryBorders = datasource
    CV-->>Main: resolve datasource
    deactivate CV

    Note over Main,Cesium: Later — camera sync updates visibility
    Main->>Cesium: compute showGlobe
    Main->>Cesium: set globe.show / skyAtmosphere.show
    alt country borders present
        Main->>Cesium: set viewer._countryBorders.show = showGlobe
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped to an offline sea of blue,
GeoJSON threads each border true,
Borders blink when the globe takes stage,
Pastel tides on a quiet page,
A tiny hop — the world anew.

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat(#35): ✨ Change to offline rendering" directly and clearly summarizes the primary objective of the changeset. The code changes substantiate this title: the imagery provider is disabled, a GeoJSON-based country borders loader is added, and offline data is integrated into the application startup. The title is concise, specific, and accurately reflects the main change without unnecessary noise or vague terminology.
Linked Issues Check ✅ Passed The code changes directly address the objectives from issue #35. The imagery provider is disabled in cesiumViewer.js (eliminating the online OSM dependency), a loadCountryBorders function is added to load offline GeoJSON data from a local file, and the globe baseColor is set to a semi-transparent light blue (#D6EBF2) to resemble the OSM appearance. The offline GeoJSON map is called during application initialization in main.js, and country border visibility is synchronized with globe visibility in cameraSync.js. These changes collectively replace online rendering with offline GeoJSON rendering while maintaining visual parity with the original OSM appearance.
Out of Scope Changes Check ✅ Passed All significant code changes are directly related to implementing offline rendering as specified in issue #35. The cesiumViewer.js changes disable online imagery and load offline GeoJSON data, cameraSync.js extends visibility controls to country borders, and main.js orchestrates the initialization of the offline rendering system. The potreeViewer.js camera position adjustment appears to be necessary tuning for proper viewing of the new offline globe setup, and the new Cypress test file validates the offline rendering functionality. No unrelated or extraneous changes are present.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 35-change-to-offline-rendering

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d46c7fe and 74389ce.

📒 Files selected for processing (1)
  • cypress/e2e/globeRendering.cy.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • cypress/e2e/globeRendering.cy.js

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbit coderabbit bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/cesiumViewer.js (2)

24-24: Globe base color set appropriately.

The semi-transparent pastel blue (#D6EBF2 at 50% alpha) provides a clean background for the offline country borders. Consider moving this to config.js if the color scheme might change in the future.


31-36: Consider extracting hardcoded values to configuration.

The GeoJSON file path and styling options (colors, stroke width) are hardcoded. While this works for the current implementation, moving these to config.js would improve maintainability if adjustments are needed.

Example configuration in config.js:

export const COUNTRY_BORDERS_CONFIG = {
  path: '/data/geo/world_simplified.geojson',
  stroke: { color: '#000000', alpha: 0.2 },
  fill: { color: '#F2EFE9' },
  strokeWidth: 1.0
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4af9107 and 205544e.

📒 Files selected for processing (3)
  • src/cameraSync.js (1 hunks)
  • src/cesiumViewer.js (1 hunks)
  • src/main.js (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/cesiumViewer.js (1)
src/potreeViewer.js (1)
  • viewer (14-16)
src/main.js (1)
src/cesiumViewer.js (1)
  • loadCountryBorders (29-45)
⏰ 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). (1)
  • GitHub Check: prettier
🔇 Additional comments (3)
src/cameraSync.js (1)

36-38: LGTM: Visibility synchronization implemented correctly.

The guard pattern appropriately handles the optional _countryBorders property and ensures visibility stays in sync with the globe. Note that using _countryBorders as a pseudo-private property on the viewer object works but deviates from strict encapsulation—consider whether a more formal state management approach might benefit future extensions.

src/cesiumViewer.js (1)

20-20: LGTM: Imagery provider correctly disabled for offline rendering.

Setting imageryProvider: false appropriately disables the default online OSM tiles, which aligns with the PR objective to implement offline rendering.

src/main.js (1)

13-13: The GeoJSON file exists and will be accessible at runtime.

The file public/data/geo/world_simplified.geojson exists and is correctly referenced in the code. Vite (the project's build tool) serves files from the public/ directory at the root path / by default, so the path /data/geo/world_simplified.geojson used in loadCountryBorders() will correctly resolve at runtime. No issues found.

Copy link

@coderabbit coderabbit bot left a 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)
src/main.js (1)

13-17: Error handling successfully addresses previous review feedback.

The try-catch block properly handles potential GeoJSON loading failures and logs meaningful error information. The application gracefully continues with degraded functionality if borders fail to load.

Optional enhancement: Consider adding a user-facing notification (e.g., a toast or alert) when country borders fail to load, so users understand why the globe may appear different than expected.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e928f4 and fe5b4ab.

📒 Files selected for processing (2)
  • src/cesiumViewer.js (1 hunks)
  • src/main.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/cesiumViewer.js
🧰 Additional context used
🧬 Code graph analysis (1)
src/main.js (1)
src/cesiumViewer.js (1)
  • loadCountryBorders (38-54)
⏰ 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). (1)
  • GitHub Check: prettier
🔇 Additional comments (1)
src/main.js (1)

2-2: LGTM! Import statement is correct.

The addition of loadCountryBorders to the import list is properly structured and necessary for the offline rendering feature.

Copy link

@coderabbit coderabbit bot left a 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)
src/cesiumViewer.js (1)

38-54: Function implementation is correct and well-documented.

The function properly loads and configures the GeoJSON data source with appropriate styling for offline rendering. The JSDoc is clear and helpful.

Two optional refinements to consider:

  1. Hard-coded file path (line 40): Consider accepting the path as an optional parameter with a default value. This would improve testability and flexibility.

  2. Mutating viewer object (line 51): Storing _countryBorders directly on the Cesium viewer instance is a code smell—you're adding custom properties to a library-owned object. While this pattern appears consistent with your codebase (used in cameraSync.js), consider maintaining a separate application state object for these references instead.

Example for making the path configurable:

-export async function loadCountryBorders(viewer) {
+export async function loadCountryBorders(viewer, geoJsonPath = '/data/geo/world_simplified.geojson') {
   const dataSource = await Cesium.GeoJsonDataSource.load(
-    '/data/geo/world_simplified.geojson',
+    geoJsonPath,
     {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe5b4ab and 23944bf.

📒 Files selected for processing (2)
  • src/cesiumViewer.js (1 hunks)
  • src/potreeViewer.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/potreeViewer.js
⏰ 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). (1)
  • GitHub Check: prettier
🔇 Additional comments (1)
src/cesiumViewer.js (1)

20-25: Offline rendering configuration looks good.

The changes correctly disable the online imagery provider and set an appropriate ocean-like base color. The semi-transparent alpha (0.5) allows the GeoJSON land masses to layer nicely over the globe.

Copy link

@coderabbit coderabbit bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
cypress/e2e/globeRendering.cy.js (1)

3-3: Use Cypress baseUrl instead of hard-coded URL.

The hard-coded localhost:5173 URL may fail in different environments (CI/CD, different port configurations). Configure baseUrl in cypress.config.js and use a relative path.

-    cy.visit('http://localhost:5173/#')
+    cy.visit('/#')

Then ensure cypress.config.js contains:

{
  e2e: {
    baseUrl: 'http://localhost:5173'
  }
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23944bf and d46c7fe.

📒 Files selected for processing (1)
  • cypress/e2e/globeRendering.cy.js (1 hunks)
⏰ 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). (1)
  • GitHub Check: prettier

@mariewah mariewah self-requested a review October 20, 2025 10:33
Copy link
Member

@mariewah mariewah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :D

Copy link
Member

@tobiaobr tobiaobr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good fix. Code rabbit might be a bit too eager though. 🔥

@kleinc kleinc merged commit 3f46613 into dev Oct 20, 2025
2 checks passed
@kleinc kleinc deleted the 35-change-to-offline-rendering branch October 20, 2025 11:09
Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change to offline rendering
3 participants