Ga naar inhoud

Hoe werkt dit: de sportparkkaart

De wegwijzer beantwoordt de vraag “bij wie moet ik zijn”. De sportparkkaart beantwoordt de andere vraag: waar is het. Je ziet welke velden, gebouwen, kleedkamers en kasten er zijn, wie ze beheert, wat erin ligt, wie erbij kan en van wie ze zijn.

Voor de club

De kaart

Op /sportpark staat het park met alles wat eraan hangt. Tik op een vlak en je ziet wie het beheert, wie de eigenaar is, wat erin ligt en wie er een sleutel van heeft. Staat er een getal bij, dan zit daar iets: materiaal, een voorziening of een sleutel.

Een gebouw kun je openen. Dan zie je de ruimtes erin, met hetzelfde beeld: de kaart van het clubhuis met de kleedkamers erop. Boven de kaart staat het pad terug.

De kaart rekent in meters. Het park heeft een plan (zo breed, zo lang, het noorden boven) en alles ligt daar in meters op. Een veld is het gras inclusief uitloop. Daarin ligt de belijning met haar eigen maat, en die volgt de regels: op een veld van 100 bij 64 is het strafschopgebied nog steeds 16,5 meter diep. Eén veld kan meer dan één belijning dragen, bijvoorbeeld het seniorenveld in wit en twee velden voor 8 tegen 8 dwars erop in blauw. Kunstgras heeft een andere kleur dan gras.

Maat en inrichting

Tik op een vlak en kies Maat en inrichting. Daar staat alles in getallen: de plek en de maat in meters, de draaiing, en per soort wat erbij hoort.

  • Veld: de ondergrond en de belijningen. Elke belijning heeft een sjabloon (KNVB 11 tegen 11, 8 tegen 8, 6 tegen 6, of alleen een omtrek), een kleur, een lengte en breedte, een middelpunt en een draaiing. Bij een KNVB-sjabloon staat de marge erbij als hint. Buiten de marge opslaan kan gewoon, want elk park is anders.
  • Tribune: rijen, optrede, aantrede, hoogte van de eerste rij, zitten of staan, zij- en achterwand, en het dak met zijn oversteek, hoogtes, boeiboord en kolommen. De dakrand is vanzelf een rail voor borden.
  • Gebouw: hoogte van de muren, daktype (plat, zadeldak in twee richtingen, lessenaarsdak) en de plattegrond als hoekpunten, met een rechthoek en een L-vorm als vertrekpunt.
  • Rails: waar borden aan hangen. Zonder eigen rails gelden de standaardrails van de soort: vier zijden om een veld, de dakrand van een tribune, de lijn van een hek.
  • De rest: een hoogte.

Op de kaart zelf heeft de laatst gekozen locatie twee handgrepen. De hoek rechtsonder verandert de maat (Maat aanpassen) en de knop erboven draait (Draaien). Loslaten bewaart.

Het park in de wereld

Boven de kaart van het park staat Plan van het park: hoe groot het terrein is, waar het noorden zit en het middelpunt als RD-coördinaat. Zoek het adres op (PDOK) of vul de coördinaat in. Daarna haalt Luchtfoto ophalen (PDOK) de luchtfoto één keer op en legt hem onder de kaart, gedraaid en op schaal. Met Ondergrond weghalen haal je hem weer weg.

Ruimtelijk

De weergave Ruimtelijk toont het park als maquette: velden met belijning, gebouwen met hun dak, de tribune met rijen en dak, dug-outs, lichtmasten, ballenvangers, hekken, groen, parkeren en terras. Je hebt drie standpunten (boven, schuin, rondom) en een camera die je zelf draait. De zon staat waar hij op de gekozen datum en tijd echt staat. Je ziet dus welk veld om zeven uur in de schaduw van de tribune ligt. In het donker gaan de lichtmasten aan. Tik op iets en het detail opent. Afbeelding opslaan bewaart het beeld als PNG. Bewerken doe je in het bovenaanzicht.

Verkennen op ooghoogte

Verkennen zet de camera op ooghoogte, op een bereikbaar punt bij het midden van het park. Wil je ergens anders beginnen, tik dan eerst op de grond in het overzicht. Daarna:

  • Tik op de grond om ergens heen te lopen. Een stip toont de bestemming en de statusregel boven de kaart zegt waar je heen gaat. Een nieuwe tik kiest een nieuwe bestemming.
  • Sleep of veeg om rond te kijken. Lopen en kijken zijn onafhankelijk van elkaar.
  • Stoppen en Escape stoppen de beweging. Escape in rust en Terug naar overzicht brengen je terug naar de camera zoals die stond vóór het verkennen.
  • Tik op een gebouw of ander object en het detail opent zoals altijd. Het lopen pauzeert dan. In het detail staat Loop hierheen. Zo kies je ook met de lijst of het toetsenbord een bestemming. Toetsenbord op de kaart: pijltjes links en rechts draaien, omhoog en omlaag kantelen.
  • Routes blijven buiten gebouwen, tribunes, dug-outs en hekken en gaan door poorten. Een plek die niet te bereiken is, geeft een melding en de camera blijft staan. Heb je ingesteld dat je liever minder beweging ziet, dan verplaatst de camera direct in plaats van te lopen.

Onder Licht, kwaliteit en sfeer staat de schakelaar Levendig sportpark: fictieve bezoekers op bereikbare routes en een voorbeeldwedstrijd op het hoofdveld. Het is alleen sfeerbeeld en geen wedstrijdinformatie. De schakelaar staat standaard uit en het beeld komt niet in de opgeslagen afbeelding.

Plattegrond als SVG bewaart het bovenaanzicht als vectorbestand met schaalbalk en noordpijl. Dat gebruik je om af te drukken voor het noodplan, de sponsorkaart of het toernooiboekje.

Wie de boom beheert (terreincommissie of bestuur), sleept de vlakken naar hun plek op het terrein. Wat je niet sleept, legt de app zelf neer in een raster, en nooit bovenop iets dat al een plek heeft. Zo is er altijd een kaart om op te klikken, ook bij een club die net begint.

De Lijst toont dezelfde inhoud als de kaart. Wie met een schermlezer werkt, gebruikt de lijst.

Zoeken

Het zoekveld bovenaan zoekt op naam en op code, door de hele boom heen. Typ “kleed” en je krijgt de kleedkamers. Typ “KK1” en je krijgt er één. Je hoeft dus niet te weten waar iets hangt om het te vinden.

Wat er ligt

Bij een kast of hok staat wat erin ligt. Dat komt uit de materialenmodule. Het is dezelfde voorraad en geen tweede lijst. Verhuist een artikel naar een ander hok, dan verhuist het hier mee.

Het sleutelplan

Onder de kaart staat wie welke sleutel of tag heeft en sinds wanneer. Dit is de bijlage bij het pachtcontract. Het aantal staat op de sleutel, omdat er nooit meer uit kunnen dan er zijn. Is de laatste uitgegeven, dan zegt de app dat er eerst één terug moet.

Innemen laat de regel staan. Wie de sleutel wanneer had, is het halve nut van een sleutelplan. “Nu heeft niemand hem” is te weinig als er iets gebeurt.

Voorzieningen

AED, EHBO-koffer, brandblusser, meterkast, camera. Bij een camera vraagt de app om de kijkrichting, de bewaartermijn en of er een informatiebordje hangt. Dat zijn precies de gegevens die de AVG eist. Zo komen het cameraplan en het verwerkingsregister uit dezelfde bron, in plaats van uit twee documenten die uit elkaar lopen.

Archiveren, niet verwijderen

Een locatie met inhoud gaat niet weg. Hangen er ruimtes onder, ligt er materiaal, of hangt er een sleutel of voorziening aan, dan zegt de app wat er in de weg staat. Ruim dat eerst op. Daarna archiveer je de locatie en blijft ze leesbaar in de geschiedenis.

Wie mag wat

Kaart lezen Boom beheren Sleutels uitgeven Voorzieningen
Kaderlid ja
Commissieleider ja
Terreincommissie (module locaties_beheer) ja ja ja ja
Bestuurslid ja ja ja ja
Clubbeheerder ja ja ja ja

Lezen mag iedereen in het kader, ook het sleutelplan. Waar de AED hangt en wie de sleutel van het ballenhok heeft, is geen geheim. Het is precies de vraag die dit scherm moet beantwoorden.

Voor wie eraan bouwt

  • Migratie 20260910130000_module_k_sportpark.sql: voorziening, sleutel, sleuteluitgifte, plus app.mag_locaties_beheren, app.locatie_archiveren, app.sleutel_uitgeven en app.sleutel_innemen.
  • Migratie 20260911150000_plan_in_metres.sql: de kaart in meters. kaart_positie heet placement en bevat x_m, y_m, w_m, h_m, rotation_deg op het plan van de ouder. Een bordpositie is een punt. Het plan van het park staat in attributen.plan van het sportpark (w_m, h_m, north_deg, origin_rd). Er zijn twee functies: app.move_location (slepen, recht mag_kaart_inrichten) en app.resize_location (maten, recht mag_locaties_beheren). Het plan gaat via set_location_attributes. Nieuwe soorten in de boom: tribune, dugout, lichtmast, ballenvanger, hek, parkeerplaats, terras, groen. Hun tekening volgt later.
  • Belijning is rekenwerk en geen plaatje. src/lib/pitch/templates.ts rekent per sjabloon (knvb-11, knvb-8v8, knvb-6v6, outline) de lijnen uit lengte en breedte. Wat een veld is, staat in attributen.pitch van de locatie, met een Zod-schema in src/lib/pitch/pitch.ts: ondergrond en een lijst belijningen, elk met eigen maat, kleur, middelpunt en draaiing. Een veld zonder attributen krijgt een passend sjabloon uit readPitch, zodat de kaart nooit een groen blok zonder lijnen toont.
  • src/components/map/pitch-drawing.tsx tekent een veld als SVG met de viewBox in meters. Beide kaarten gebruiken hem. De lijnkleuren komen uit --kaart-lijn-* in globals.css.
  • Migratie 20260912090000_grounds_objects.sql: app.set_location_attributes (één samenvoeging op het hoogste niveau van attributen, rechten via mag_locaties_beheren) en bordposities_genereren met een parameter rail. De schema’s per soort staan in src/lib/grounds/objects.ts (stand, building, object, rails) en de standaardrails in src/lib/grounds/rails.ts. Een bordpositie hangt aan een rail van haar drager (attributen.rail). Zonder rail geldt de oude indeling per zijde.
  • Het blad “Maat en inrichting” is inrichting.tsx, de acties staan in src/modules/sportpark/inrichting-acties.ts. De luchtfoto en het adres komen van PDOK (src/lib/geo/, ADR 44). De zonstand komt uit src/lib/sun.ts.
  • Waar het rekenwerk woont en waarom locatie.type Nederlands blijft, staat in ADR 45. Slepen is mag_kaart_inrichten (ook de sponsorcommissie). Maten en inrichting zijn mag_locaties_beheren.
  • De maquette staat in src/components/map/scene/ en wordt lui geladen (ADR 43). Ze leest dezelfde placement en attributen als het bovenaanzicht en tekent niets uit bestanden.
  • Verkennen en sfeer (ADR 64). Routes: src/lib/grounds/navigation.ts (raster, A*, veilige vereenvoudiging) en ambient-motion.ts (bezoekersroutes, wedstrijdlus), beide met unittests. De scène vertaalt haar gegevens in scene/navigation-input.ts met dezelfde lezers als de meshes. scene/walk-controller.tsx bezit de camera tijdens verkennen (CameraRig is dan niet gemount), scene/ambient-actors.tsx tekent de figuren met instancing en scene/scene-activity.ts is de enige planner voor frames, zichtbaarheid en kwaliteit. De wrapper is role="group" met toetsenbord. e2e zoekt daarop. Headless controle: node scripts/park-walk-check.mjs na node scripts/park-preview.mjs.
  • Het terrein uit een template (ADR 64). supabase/seed/grounds/pvcv.v1.json is de bron. node scripts/grounds-template.mjs --as seed genereert supabase/seed/pvcv/97b-sportpark-terrein.sql (97a houdt alleen records zonder geometrie). --as demo genereert de functie app.demo_terrein in migratie 20260916120000_terrein_template.sql. app.terrein_bordrun legt bordposities op een rail met vrije poorten en dug-outs. Een positie met een bord verhuist alleen met een bevestiging per code. De toolingtest scripts/grounds-template.test.mjs bewaakt dat seed en migratie bij de template horen. Voor bestaande omgevingen is er scripts/grounds-apply.mjs. Zie het draaiboek in deploy/README.md.
  • Geen nieuwe boom. locatie uit fase 0 kon dit al: type, code, ouder, beheerder, eigenaar, kaartpositie en vrije attributen (ADR 14). Deze module maakt hem beheerbaar en hangt er drie dingen aan. Dat was de belofte van fase 0 en die is uitgekomen.
  • Eén kaartcomponent voor twee kaarten. src/components/map/floor-plan.tsx doet het moeilijke deel: kantelen, schalen, schuiven, slepen, en de klik na een sleep opeten. Hij rekent pixels per meter uit en geeft die aan zijn inhoud. Niets wordt met een CSS-schaal vergroot, zodat tekst op elke zoomstand de maat van het designsysteem houdt. De bordenkaart (module E) en deze kaart geven er allebei hun eigen inhoud in mee via een functie. Er is geen aparte code per kaartsoort (architectuur §5.6) en geen 3D-bibliotheek (ADR 34).
  • Het lezen van placement en het plan staat in src/lib/plan.ts, want twee modules en een component rekenen ermee.
  • layoutChildren telt bij het raster alle kinderen mee, ook die al een plek hebben. Anders is er bij één vrij kind maar één vak, en dat ligt gegarandeerd over het veld heen dat er al staat. Het vlak wordt dan onaanklikbaar.
  • Wat waar ligt, komt via de index van module G en niet via een join. De sportparkkaart kent artikel niet. Ze vraagt het op bij de materialenmodule (regel: geen join over moduletabellen heen).
  • Welke locatie open staat, zit in de URL (?op=) en niet in de state. Een verdieping is dan deelbaar en de terugknop van de browser werkt gewoon.
  • Nog niet gebouwd uit module K: de kleedkamerindeling van vandaag (wacht op de Sportlink-koppeling), ruimtes reserveren voor een evenement, en een eigen plattegrond als ondergrond per gebouw. Dat laatste kan al wel: app.plattegrond_koppelen bestaat sinds module E en de component tekent hem.

Visueel inrichten en meerdere sporten

Kies Park inrichten om objecten te plaatsen. De Objectbibliotheek bevat sportvelden, gebouwen, tribunes, paden, groen en voorzieningen. Geef elk nieuw object een naam en kies Object plaatsen. Voetbal is de standaard. De overige sporten en een vrij speelvlak kies je in de bibliotheek of bij de veldinrichting. Kies je een sport, dan blijft je belijning staan. Wil je de belijning vervangen, kies dan bewust Belijning vervangen door sportsjabloon. Controleer de werkelijke maten van je vereniging, want de tekeningen zijn indicatief.

Sleep op de plattegrond: het raster klikt op meters en nabijgelegen objectranden. Met de maatgrepen schaal en draai je de selectie. Ongedaan maken en Opnieuw gelden voor deze geometrische bewerkingen en niet voor alle formulieren. Selectie vastzetten geldt zolang deze pagina openblijft. Selectie dupliceren kopieert de geometrie, niet de kinderen of de gekoppelde administratie. Bij een versieconflict vernieuw je de pagina. Een wijziging van een collega wordt niet overschreven. Hoekpunten bepalen de parkcontour en een pad. Kruisende contouren worden geweigerd.

Een foto breng je op schaal (Foto op schaal brengen) met twee punten en een bekende afstand, of met de exacte fotobreedte. Locaties blijven daarbij op hun plek. De luchtfoto is een optionele laag bij het inrichten. Ruimtelijk toont de maquette. Boven, Schuin en Rondom kiezen de camera. Verkennen zet je op ooghoogte (zie boven). Licht, kwaliteit en de sfeerschakelaar staan onder extra opties. De kwaliteit Licht helpt op tragere apparaten. De 2D-kaart en de lijst blijven beschikbaar als WebGL uitvalt. Met Afbeelding opslaan maak je een PNG. De SVG is een plattegrond.

Wie borden mag bekijken, ziet ook de bordenlaag en een lijst met alle bordposities. De laag bevat sponsornaam en status, geen contractbedragen. Het detail verwijst naar de bordenmodule.

Hekwerk, poorten en borden samen inrichten

  1. Kies Park inrichten, selecteer het veld of de tribune en open Maat en inrichting.
  2. Kies Hekken en borden. Met Hek op bestaande bordlijnen krijgt de bestaande omtrek zichtbaar hekwerk. Of kies Heksegment tekenen en tik een begin- en eindpunt aan.
  3. Selecteer de gewenste lijn. Stel de hekhoogte in en voeg poorten toe met afstand vanaf het begin en breedte. Onder Exacte segmentmaten en richting kun je dezelfde punten ook met het toetsenbord instellen. Op een tribune stel je ook de basishoogte in.
  4. Kies Rails bewaren. Openingen mogen elkaar niet overlappen of buiten het segment vallen. Een poort over een bestaande bordpositie wordt geweigerd. Verplaats die positie eerst.
  5. In hetzelfde paneel zet je bordposities klaar met zijdenaam, aantal en maat (Bordposities klaarzetten). Het voorbeeld toont de verdeling en de doorgangen. Een verdeling over een poort past niet. Pas dan het aantal of de maat aan. Bestaande posities verplaats je via de keuzelijst en de railbediening, zonder hun bordregistratie te vervangen.

Hekwerk beweegt en draait mee met het veld of de tribune. De weergaven en de SVG-export gebruiken dezelfde segmenten. Met Hek verbergen, bordlijn behouden blijven de bordlijn en de bijbehorende posities staan. Bordposities klaarzetten registreert geen sponsorcontract en markeert geen bord als gemonteerd.

Precies plaatsen en de hele kaart terugvinden

Een korte tik op een maatgreep verandert niets. Breekt de aanraking af, dan gaat het object terug naar de eerdere maat. Bij vergroten blijft de tegenoverliggende hoek staan, ook als het object gedraaid is. Met focus op de maatgreep vergroten of verkleinen de pijltjestoetsen in stappen van 10 centimeter. Met Shift is dat een meter. Op de draaigreep draaien de pijltjestoetsen één graad, of 15 graden met Shift.

In de ruimtelijke weergave brengt Heel park je terug naar het overzicht. Op een telefoon kun je in het begin gewoon over de kaart heen scrollen. Kies Kaart bedienen om de camera met aanraking te bewegen. Pagina scrollen geeft het scherm weer vrij. Tijdens Verkennen bedien je de wandeling. De nachtlucht blijft donker in zowel de lichte als de donkere kleurstand van de app.

Van een plek naar het werk

Open een locatie op de kaart of in de Lijst en kies Meldingen en projecten op deze plek. Je vindt er de meldingen en projecten die je mag lezen. Een besloten melding wordt niet zichtbaar doordat je dezelfde locatie kunt openen. Een project verschijnt hier nadat het bestuur of de projectleider deze locatie bij het project heeft gekoppeld.

Met Meld een probleem beschrijf je wat er mis is. De beheercommissie staat al gekozen als die actief is. Controleer de ontvanger. Zonder beheercommissie moet je die zelf kiezen. De ontvanger handelt de melding af via Meldingen en vragen. Daar staat ook de link terug naar de locatie. Een latere wijziging van de beheercommissie verplaatst oude meldingen niet. Gebruik daarvoor Stuur door bij de melding.

Bij een fout blijven je onderwerp, toelichting en ontvanger staan. Opnieuw proberen met dezelfde invoer maakt geen tweede melding. De locatie moet nog actief zijn om een nieuwe melding te maken. Bestaande meldingen blijven na archiveren beschikbaar voor hun lezers.