Skip to content

Barrios map : more placement checks (area and sound zone)#206

Draft
davinov wants to merge 11 commits intopeterdrier:mainfrom
davinov:barrios-map-more-checks
Draft

Barrios map : more placement checks (area and sound zone)#206
davinov wants to merge 11 commits intopeterdrier:mainfrom
davinov:barrios-map-more-checks

Conversation

@davinov
Copy link
Copy Markdown

@davinov davinov commented Apr 10, 2026

Builds on top of #205 (to be merged first! I'll rebase this once it's done - only a170232 and 8aecf2f should appear in the diff)

Display warnings for these two cases:
Screenshot from 2026-04-10 12-30-51
Screenshot from 2026-04-10 12-30-55

davinov and others added 11 commits April 10, 2026 08:14
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
History (and Restore for editors) is now accessible from the zone click
popup, removing the need to enter edit mode first. The toolbar history
button is removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Track previewCampSeasonId in state so overlapsOtherCamps excludes the
barrio whose history is being previewed, matching the existing behavior
for edit mode via activeCampSeasonId.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows a warning in the click popup, the live draw label, and the static
polygon label (⚠️ prefix) when a barrio's drawn area is more than 50%
larger or smaller than the space requested in the camp form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aced in

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@peterdrier
Copy link
Copy Markdown
Owner

Code Review

Overall: Good feature addition — area size and sound zone placement checks give useful feedback to city planners. Reviewing only the new commits (a170232, 8aecf2f) on top of #205. A few items to discuss.

Query Pattern Change: Server-side evaluation

  • CityPlanningService.cs GetCampPolygonsAsync and GetCampSeasonsWithoutCampPolygonAsync: Both methods changed from server-side projection (.Select(...).ToListAsync()) to client-side evaluation (.ToListAsync() followed by .Select(...).ToList()). This was done to call the SpaceSizeToSqm() helper which can't be translated to SQL. At this project's scale (~500 users, handful of camps), this is fine — but worth noting that the full entity graph is now materialized into memory. The trade-off is acceptable here.

Potential Issue: SpaceSizeToSqm enum-to-double mapping

  • CityPlanningService.cs SpaceSizeToSqm: This maps each SpaceSize enum value to its corresponding square meter value via a switch expression. This is correct and readable, but it duplicates the numeric knowledge embedded in the enum names. If a new SpaceSize value is ever added, both the enum and this switch must be updated. Consider adding a comment noting this coupling, or potentially deriving the value from the enum name (though the explicit switch is clearer). Not a blocker.

JavaScript: getSoundZoneOutOfRange logic

  • geometry.js getSoundZoneOutOfRange: The function returns false when campSoundZone === 5. Looking at the SOUND_ZONE_NAMES map ({ 0: 'blue', 1: 'green', 2: 'yellow', 3: 'orange', 4: 'red' }), value 5 has no corresponding name, so this is the "Unknown/None" sentinel. This seems correct but is fragile — the magic number 5 should ideally come from the server-side SoundZone enum (which presumably has 5 values, 0-4). If the enum gains a 6th value, this JS code would silently skip it. Consider adding a comment explaining what 5 represents.

JavaScript: Silent catch in getSoundZoneOutOfRange

  • geometry.js line ~530 (in the diff): The catch { /* ignore */ } inside the loop swallows all exceptions. Per the project's code review rules, silent exception swallowing is flagged. However, this is client-side JS geometry code where turf.js can throw on malformed GeoJSON, and logging to console would be noisy during normal operation. The empty catch is consistent with the existing patterns in this file (e.g., overlapsOtherCamps). Acceptable given context, but a console.debug would be slightly better for debugging.

JavaScript: Centroid-based sound zone check

  • geometry.js getSoundZoneOutOfRange: Uses turf.centroid(feature) + booleanPointInPolygon to determine which sound zone a barrio falls in. This means a barrio whose centroid is in one zone but whose area spans two zones will only be checked against the centroid's zone. This is a reasonable simplification — checking polygon intersection against all zones would be more accurate but significantly more complex. Worth noting in case users report false positives/negatives for barrios on zone boundaries.

Ratio thresholds (1.5x / 0.5x)

  • edit.js and geometry.js: The area-vs-requested-size warning uses ratio > 1.5 (50% larger) and ratio < 0.5 (50% smaller). These thresholds appear in three places: buildCampPolygonFeatures, onCampPolygonClick popup, and updateSaveButton draw label. Consider extracting these as named constants (e.g., const SIZE_RATIO_UPPER = 1.5, SIZE_RATIO_LOWER = 0.5) to avoid drift if they need adjustment later.

Suggestions

  • The warning messages in JS ("Area much larger than requested", "Sound zone doesn't match this area") are hardcoded English, same pattern noted in City planning: geojson properties documentation, fixes on UX for history #205. These are user-facing strings that ideally should go through localization.
  • The getCampSoundZone and getSpaceRequirementSqm helper functions in edit.js are clean — they check both campPolygons and campSeasonsWithoutPolygon arrays, which handles the case where a barrio is being newly placed.

Thanks for the contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants