feat: NDVI Satellite Imagery Integration (Issue #53)#62
Conversation
|
@Excalibur677 is attempting to deploy a commit to the karan3431's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Warning Review limit reached
More reviews will be available in 43 minutes and 12 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughAdds full-stack NDVI satellite imagery support. A new ChangesNDVI Satellite Imagery via Sentinel Hub
Sequence Diagram(s)sequenceDiagram
participant User
participant FarmMap
participant NDVILayer
participant useNDVI
participant BackendAPI
participant SentinelHub
rect rgba(34, 139, 34, 0.5)
Note over User,FarmMap: Toggle overlay
User->>FarmMap: Click "Show NDVI"
FarmMap->>NDVILayer: render with visible=true
end
rect rgba(70, 130, 180, 0.5)
Note over NDVILayer,BackendAPI: Data fetch
NDVILayer->>useNDVI: fetchNDVI(dateFrom, dateTo)
useNDVI->>BackendAPI: GET /api/ndvi?farm_id=...
alt ndvi_cache hit (<24h)
BackendAPI-->>useNDVI: cached ndvi_min/max/mean + bbox
else cache miss
BackendAPI->>SentinelHub: Sentinel-2 L2A evalscript
SentinelHub-->>BackendAPI: TIFF data
BackendAPI->>BackendAPI: compute NDVI stats
BackendAPI-->>useNDVI: computed ndvi_min/max/mean + bbox
end
useNDVI-->>NDVILayer: ndviData
end
rect rgba(184, 134, 11, 0.5)
Note over NDVILayer,User: Render overlay
NDVILayer->>NDVILayer: draw canvas gradient → Leaflet imageOverlay
NDVILayer->>User: show NDVILegend + opacity slider
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
🎉 Thanks for your contribution, @Excalibur677! Please make sure CI passes and the checklist in the PR template is complete. A maintainer will review this soon. — The AgroNavis team |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
backend/supabase/migrations/20260616000000_ndvi_cache.sql (1)
13-14: ⚡ Quick winUse a composite index for the actual cache lookup path.
The current lookup pattern is
farm_idfilter +created_at DESCsort +LIMIT 1. A composite index will avoid extra sorting work as cache rows grow.⚙️ Suggested migration tweak
-create index if not exists ndvi_cache_farm_id_idx on ndvi_cache(farm_id); -create index if not exists ndvi_cache_created_at_idx on ndvi_cache(created_at desc); +create index if not exists ndvi_cache_farm_created_at_idx + on ndvi_cache(farm_id, created_at desc);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/supabase/migrations/20260616000000_ndvi_cache.sql` around lines 13 - 14, Replace the two separate indexes ndvi_cache_farm_id_idx and ndvi_cache_created_at_idx with a single composite index on the (farm_id, created_at desc) column combination. This composite index will optimize the actual cache lookup query pattern which filters by farm_id, orders by created_at descending, and limits to 1 result, eliminating the need for additional sorting work as the table grows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/main.py`:
- Around line 860-865: The cache lookup in the supabase table select ignores the
requested date_from and date_to parameters, allowing mismatched cache hits
across different date ranges. Additionally, the cached response returns raw
table rows while fresh responses include a resolution field, creating an
inconsistent API schema. Fix this by including date_from and date_to in the
cache query filtering logic alongside farm_id, and normalize the cached response
object to include the same fields (such as resolution) that are present in fresh
responses before returning it.
- Around line 883-884: The coordinate validation at the farm location check uses
truthiness evaluation with `if not lat or not lng:`, which incorrectly rejects
valid zero values for coordinates on the equator or prime meridian. Replace the
truthiness checks with explicit `None` comparisons so that `0.0` values are
treated as valid coordinates while still catching missing (None) values. Change
the condition to check `if lat is None or lng is None:` instead.
- Around line 922-925: Add a guard check before the lines that access
ndvi_data[0] to ensure that ndvi_data is not empty. Before assigning ndvi_array
from ndvi_data[0], verify that ndvi_data has at least one element; if it is
empty, handle this gracefully by either returning an appropriate error response
or setting default values. This prevents the IndexError from being raised when
Sentinel Hub returns no scenes for the requested interval.
In `@frontend/src/components/NDVILayer.tsx`:
- Around line 22-38: The canvas gradient being created in the NDVILayer
component is static and does not represent actual NDVI data values from the
satellite/raster source. Replace the hardcoded canvas-based gradient approach
with either (1) a real raster/tiles data source from the backend (or Sentinel
Hub WMS/WCS/Process output) that maps actual pixel values to the color scale, or
(2) if that is out of scope for this PR, update the layer label and any
documentation to clearly indicate that this is an illustrative overlay rather
than actual NDVI imagery. The current implementation where a fixed gradient is
created, converted to a data URL via canvas.toDataURL(), and then passed to
L.imageOverlay() needs to be replaced with logic that either fetches and renders
real data or appropriately disclaims the synthetic nature of the visualization.
In `@frontend/src/components/NDVILegend.tsx`:
- Around line 35-37: The legend labels in NDVILegend.tsx contain corrupted
characters (displayed as `�`) in the range specifications within the labels for
entries like 'Moderate (0.4–0.6)', 'Sparse (0.2–0.4)', and elsewhere. Replace
all occurrences of the corrupted `�` character with the correct dash character
(en-dash or minus sign) in the range labels throughout the file. This issue
appears at lines 35-37 in the legend color definitions and also at line 49 in
the average line label, so ensure both locations are corrected to display the
range separators properly.
---
Nitpick comments:
In `@backend/supabase/migrations/20260616000000_ndvi_cache.sql`:
- Around line 13-14: Replace the two separate indexes ndvi_cache_farm_id_idx and
ndvi_cache_created_at_idx with a single composite index on the (farm_id,
created_at desc) column combination. This composite index will optimize the
actual cache lookup query pattern which filters by farm_id, orders by created_at
descending, and limits to 1 result, eliminating the need for additional sorting
work as the table grows.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 428abb86-8818-4cf7-90c4-9dfcf41eafb3
📒 Files selected for processing (8)
.env.examplebackend/main.pybackend/requirements.txtbackend/supabase/migrations/20260616000000_ndvi_cache.sqlfrontend/src/components/FarmMap.tsxfrontend/src/components/NDVILayer.tsxfrontend/src/components/NDVILegend.tsxfrontend/src/hooks/useNDVI.ts
c6ac88d to
b9a3ee9
Compare
… empty response guard, illustrative overlay label, legend text
|
Sentinel hub is a paid one try to get the free open source alternative |
|
Hey, this feature is incredibly well-written, and the caching logic is brilliant! However, since this is an open-source project, we want to avoid relying on paid commercial APIs like Sentinel Hub. Could we refactor the backend/main.py endpoint to pull the Sentinel-2 data for free using the AWS Open Data Registry via STAC (pystac-client + rasterio) or Google Earth Engine instead? |
Hey @jpdevhub
Here's my implementation for #53.
What's changed
Backend
GET /api/ndviendpoint using Sentinel Hub's Python SDK20260616000000_ndvi_cache.sqlcreates thendvi_cachetableFrontend
Show NDVI / Hide NDVItoggle button added to the farm mapnext/dynamicto avoid SSR issues with LeafletSetup
Add these to
.env(already in.env.example):Then run:
supabase db push
Free-tier Sentinel Hub account is enough for testing.
Closes #53