-- NORMAL -- ~/projects/ma_parcelle.md project 06 / 06

ma_parcelle

Click a land parcel and the map cores it through six layers of French open data, with no account and no server.

Stack
React 19 · Vite · MapLibre
Year
2026
Repository
github.com/Popoch39/ma_parcelle ↗
A

Anatomy

7 parts · only one counts
Fig. 1 Core sample of a land parcel
  1. 01useLayerClickL9–45 ↗

    Pick a parcel

    A click reads the parcel’s ID from the map already on screen, with no network call.

    PciLayer()

    10export function PciLayer() {

    11 const { line } = OVERLAY_COLORS[useColorScheme()]

    12 const select = useSelectionStore((state) => state.select)

  2. 02zustandL3–20 ↗

    Hold on to one parcel

    One parcel open at a time, known by its 14-character cadastral code.

    SelectionState

    3interface SelectionState {

    5 idu: string | null

    10 reframe: boolean

  3. 03API CartoL63–74 ↗

    Load the parcel

    Asks the IGN cadastre for the parcel’s shape and area, in a single request.

    loadParcel()

    67export async function loadParcel(fetch: Fetch, idu: string, { signal }: LoadOptions = {}): Promise<Parcel> {

    68 const parts = parseIdu(idu)

    69 if (!parts) throw new ParcelError('invalid-idu', idu)

  4. 04fetchQueryL6–15 ↗

    Start from the parcel

    Every block starts from the cached parcel; if it is missing, they all fail together.

    parcelBlockQuery()

    11export const parcelBlockQuery = <Model>(queryClient: QueryClient, block: BlockId, idu: string, load: BlockLoader<Model>) =>

    12 queryOptions({

    13 queryKey: [block, idu],

  5. Query each source

    The browser calls the public APIs with no server in between, 15 s at most per reply.

    fetchBody()

    61async function fetchBody<T>(

    62 fetch: Fetch,

    63 url: string,

  6. 06<Block>SectionL14–25 ↗

    Stack the six blocks

    Cadastre, planning, hazards, sales, building and DPE: each loads and fails on its own.

    BLOCKS

    18export const BLOCKS = [

    19 { id: 'cadastre', Section: CadastreSection },

    20 { id: 'planning', Section: PlanningSection },

  7. 07statusL59–68 ↗

    Write the summary

    Sums up the blocks received, leaves out failed ones and flags those still loading.

    assembleSummary()

    63export function assembleSummary(blocks: readonly BlockState[]): Summary {

    64 return {

    65 facts: blocks.flatMap((block) => (block.status === 'success' ? block.data : [])),

33063 KJ 33 · ready · 0/6
Note view

Press and hold the column to drill through the strata · click the plate to run the survey againKeep your finger on the column to drill through the strata · tap the plate to run the survey again

Fig. 1 — The core barrel sets off from the parcel picked on the cadastral map and passes through six strata, one per block of the report, in the order they are shown. Each stratum is as thick as the number of requests its block sends for parcel 33063 KJ 33: 32 in all, from the browser to the public APIs, with no server. Only the cadastral crust gates the others, which are queried together; a lost stratum is missing from the log without stopping the survey.

Parts list

  1. 01 Parcel plate The engraved cadastral map. You pick a parcel by touching it: its ID (IDU) is read from the tile already on screen, with no network call. Code: src/map/layers/PciLayer.tsx, lines 9–45 ↗
  2. 02 Surface casing One casing for one hole: the selection holds a single parcel at a time. Code: src/stores/selection-store.ts, lines 3–20 ↗
  3. 03 Cadastral crust The first layer to break through: the parcel named by its IDU, from which all the others start. Code: src/api/cadastre.ts, lines 63–74 ↗
  4. 04 Core barrel It carries the parcel, taken from the Cadastre cache, down into every stratum. If the crust breaks, it brings nothing back up. Code: src/queries/block.ts, lines 6–15 ↗
  5. 05 Diamond bit It bites into each source: a GET with a 15 s timeout and a typed error (HTTP, timeout, network, invalid JSON). Code: src/api/fetch-json.ts, lines 61–91 ↗
  6. 06 Stratum rings Six bolted rings, one per block, in the order of the report. Each one loads and fails on its own. Code: src/components/report/blocks.ts, lines 14–25 ↗
  7. 07 Borehole log The summary: it is written from whatever has come up. A lost stratum, or one still loading, leaves its line blank, and the indicator stays lit while any stratum is loading. Code: src/lib/summary/summary.ts, lines 59–68 ↗