Skip to content

Add Bodemkaart soil map integration to Atlas#427

Merged
SvenVw merged 6 commits into
developmentfrom
FDM404
Jan 23, 2026
Merged

Add Bodemkaart soil map integration to Atlas#427
SvenVw merged 6 commits into
developmentfrom
FDM404

Conversation

@SvenVw
Copy link
Copy Markdown
Collaborator

@SvenVw SvenVw commented Jan 22, 2026

Summary by CodeRabbit

  • New Features

    • Integrated Bodemkaart (Soil Map) into Atlas with interactive map, satellite basemap, WMS soil layer, selectable soil features and GetFeatureInfo popups showing soil properties
    • Added Atlas header and sidebar navigation entries plus UI controls to toggle soil and field layers
    • Map view persistence across sessions and improved map interaction flows
  • Style

    • Improved map popup styling for better appearance and usability
  • Chores

    • Minor package/version bump documented

✏️ Tip: You can customize this high-level summary in your review settings.

@SvenVw SvenVw self-assigned this Jan 22, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 22, 2026

🦋 Changeset detected

Latest commit: 52dd904

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@svenvw/fdm-app Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 22, 2026

Walkthrough

Adds a Bodemkaart (Soil Map) feature to Atlas: new SoilControl and control props, header/sidebar navigation links, a full atlas/soil route with WMS raster + GetFeatureInfo handling (EPSG:3857→4326 reprojection), fields overlay and highlight, map view state persistence, and popup styling.

Changes

Cohort / File(s) Summary
Changeset
\.changeset/atlas-soil-map-integration.md
Documents package bump and notes Bodemkaart integration.
Controls & UI
fdm-app/app/components/blocks/atlas/atlas-controls.tsx, fdm-app/app/components/blocks/header/atlas.tsx, fdm-app/app/components/blocks/sidebar/apps.tsx
Adds SoilControl and showSoil/onToggleSoil props; updates FieldsControl icon; header adds "Bodemkaart" detection/link; sidebar builds atlasSoilLink and adds menu entry.
Atlas Soil Route
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx
New route: loader returns fields GeoJSON and metadata; initializes proj4/EPSG:3857; client mounts MapGL with satellite base, WMS soil layer, GetFeatureInfo flow, reprojection helper, selected-feature highlight GeoJSON, popup UI, fields overlay, map view persistence, and toggle/cleanup behavior.
Map View State tweaks
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx, fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsx
Restructures sessionStorage mapViewState retrieval to a single try/catch and ignores storage errors instead of removing stored items on parse failure.
Styling
fdm-app/app/tailwind.css
Adds MapLibre popup styles (.maplibregl-popup-close-button, .maplibregl-popup-content).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Client as Atlas Client
    participant Loader as Server Loader
    participant MapGL as Map Component
    participant WMS as WMS Server

    User->>Client: Navigate to /farm/.../atlas/soil
    Client->>Loader: request loader data (fields, calendar, mapStyle)
    Loader-->>Client: return fields GeoJSON and metadata
    Client->>MapGL: initialize map (tiles, satellite base, soil WMS layer, fields GeoJSON)
    MapGL->>MapGL: render layers

    User->>MapGL: Click map
    MapGL->>WMS: Send WMS GetFeatureInfo (EPSG:3857)
    WMS-->>Client: Return feature JSON
    Client->>Client: Reproject coords (EPSG:3857→EPSG:4326)
    Client->>MapGL: Add highlight GeoJSON & open popup

    User->>Client: Toggle Soil control
    Client->>MapGL: Show/hide soil layer and clear selections if hidden
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • BoraIneviNMI
  • gerardhros

Poem

🐰 Beneath the Atlas, soils whisper low,
WMS and fields in a gentle row.
Popups bloom where the pixels meet,
Little rabbit hops on mapping feet. 🌱✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main change: adding Bodemkaart (soil map) integration to the Atlas project, which is the central feature across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 FDM404

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.

❤️ Share

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

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.07%. Comparing base (d53536d) to head (52dd904).
⚠️ Report is 7 commits behind head on development.

Additional details and impacted files
@@             Coverage Diff              @@
##           development     #427   +/-   ##
============================================
  Coverage        88.07%   88.07%           
============================================
  Files               91       91           
  Lines             4620     4620           
  Branches          1492     1492           
============================================
  Hits              4069     4069           
  Misses             551      551           
Flag Coverage Δ
fdm-calculator 88.75% <ø> (ø)
fdm-core 86.77% <ø> (ø)
fdm-data 92.12% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot changed the title @coderabbitai Add Bodemkaart soil map integration to Atlas Jan 22, 2026
@coderabbitai coderabbitai Bot added branch:development Issue only affecting development, not the main branch (yet) enhancement New feature or request fdm-app labels Jan 22, 2026
@SvenVw
Copy link
Copy Markdown
Collaborator Author

SvenVw commented Jan 22, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 22, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai 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: 1

🤖 Fix all issues with AI agents
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.atlas.soil.tsx:
- Around line 139-153: The sessionStorage access in the viewState initializer
(getViewState, initialViewState, viewState, setViewState) isn't guarded and uses
a generic key; wrap all sessionStorage calls in try/catch to safely handle
environments where storage throws, and use a namespaced key (e.g., include a
unique prefix and farm id/calendar identifier) instead of "mapViewState" so
state doesn't collide across pages; if reading fails or parsing throws, fall
back to initialViewState, and apply the same guarded namespaced write when
persisting viewState elsewhere in this module.

Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx
@SvenVw SvenVw requested a review from gerardhros January 22, 2026 16:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai 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: 1

🤖 Fix all issues with AI agents
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.atlas.soil.tsx:
- Around line 139-157: The component reads "mapViewState" but never persists
updates; add a useEffect that watches viewState (the state initialized by
initialViewState and updated via setViewState/onViewportChange) and writes
JSON.stringify(viewState) to sessionStorage under the "mapViewState" key,
guarding with typeof window !== "undefined" and a try/catch to ignore storage
errors (e.g., private mode) so atlas views stay in sync across routes.
🧹 Nitpick comments (1)
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx (1)

70-100: Avoid any for b_lu_name to keep typing consistent.

Other atlas loaders read field.b_lu_name directly; keeping this typed avoids masking regressions.

♻️ Suggested cleanup
-                        b_lu_name: (field as any).b_lu_name,
+                        b_lu_name: field.b_lu_name,

Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx
if (savedViewState) {
try {
try {
const savedViewState = sessionStorage.getItem("mapViewState")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why within try catch? can this generate an error?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, if you are in private mode of your browser

Copy link
Copy Markdown
Collaborator

@gerardhros gerardhros left a comment

Choose a reason for hiding this comment

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

LGTM. one minor question.

Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx Dismissed
Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsx Dismissed
Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx Dismissed
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai 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: 1

🤖 Fix all issues with AI agents
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.atlas.soil.tsx:
- Around line 388-395: Replace the invalid Tailwind class "w-87.5" with the
standard arbitrary width "w-[350px]" on the grid container that renders
FieldsPanelHover; find the div element containing className "grid gap-4 w-87.5"
(the parent of <FieldsPanelHover /> which uses ZOOM_LEVEL_FIELDS and
layer={fieldsSavedId}) and update the className to use "w-[350px]" for
consistency with the codebase.
🧹 Nitpick comments (1)
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx (1)

169-248: Consider providing user feedback on GetFeatureInfo errors.

The GetFeatureInfo implementation is well-structured with proper EPSG:3857 projection and coordinate reprojection. However, when the fetch fails or returns a non-ok response (lines 215, 243-245), the user receives no feedback—the click simply does nothing.

Consider providing visual feedback for error states (e.g., a toast notification or brief inline message) so users understand why no soil data appeared.

♻️ Example error feedback approach
+import { toast } from "sonner" // or your preferred toast library

 const onMapClick = useCallback(
     async (event: MapLayerMouseEvent) => {
         // ... existing code ...
         try {
             const response = await fetch(url)
-            if (response.ok) {
+            if (!response.ok) {
+                console.error("GetFeatureInfo request failed:", response.status)
+                // Optionally: toast.error("Kon bodemgegevens niet ophalen")
+                return
+            }
             const data = (await response.json()) as FeatureCollection
             // ... rest of success handling ...
-            }
         } catch (e) {
             console.error("Failed to fetch soil info", e)
+            // Optionally: toast.error("Kon bodemgegevens niet ophalen")
         }
     },
     [showSoil],
 )

Comment thread fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx
@SvenVw SvenVw merged commit 9d3baee into development Jan 23, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

branch:development Issue only affecting development, not the main branch (yet) enhancement New feature or request fdm-app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants