From ef1734ccd44962e51dee9248935031c2b3c703f0 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Fri, 29 May 2026 17:39:18 +0200 Subject: [PATCH 1/6] =?UTF-8?q?Ajout=20des=20nouvelles=20sources=20de=20do?= =?UTF-8?q?nn=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/places.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/js/places.js b/js/places.js index 34e34f0..43d1cee 100644 --- a/js/places.js +++ b/js/places.js @@ -184,15 +184,27 @@ export class PlaceDatabase extends EventTarget { let default_database = new PlaceDatabase() await Promise.all([ + default_database.loadGeojson(new URL("../couches/aire-de-jeux.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/autogestion.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/bac-a-sable.geojson", import.meta.url), {batch: true}), default_database.loadGeojson(new URL("../couches/batiments.geojson", import.meta.url), {batch: true}), - default_database.loadGeojson(new URL("../couches/piscine.geojson", import.meta.url), {batch: true}), - default_database.loadGeojson(new URL("../couches/terrain-de-basket.geojson", import.meta.url), {batch: true}), - default_database.loadGeojson(new URL("../couches/pieces-batiments.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/braseros.geojson", import.meta.url), {batch: true}), default_database.loadGeojson(new URL("../couches/camping.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/dons.geojson", import.meta.url), {batch: true}), default_database.loadGeojson(new URL("../couches/eau-potable.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/espace-camp.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/espacemiam.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/marabouts.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/medic.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/parkings.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/pieces-batiments.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/piscine.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/poubelles.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/scenes.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/terrain-de-basket.geojson", import.meta.url), {batch: true}), + default_database.loadGeojson(new URL("../couches/wifi.geojson", import.meta.url), {batch: true}), default_database.loadGeojson(new URL("../couches/zones-interdite.geojson", import.meta.url), {batch: true}), - default_database.loadGeojson(new URL("../couches/parkings.geojson", import.meta.url), {batch: true}), - ]) + ]) default_database.buildIndex() From f7e5bb37bf09c4947435b166610b0045fbc20955 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Fri, 29 May 2026 20:41:54 +0200 Subject: [PATCH 2/6] =?UTF-8?q?Implementation=20du=20systm=C3=A8me=20de=20?= =?UTF-8?q?symbole=20sur=20l'app=20web?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- couches/autogestion.geojson | 3 +- couches/batiments.geojson | 6 +- couches/medic.geojson | 2 - couches/parkings.geojson | 2 +- couches/pieces-batiments.geojson | 50 ++++---- couches/piscine.geojson | 2 +- couches/wifi.geojson | 6 +- css/style.css | 18 +-- icons/default-marker.svg | 48 ++++++++ icons/parking.svg | 66 ++++++++++ icons/piscine.svg | 71 +++++++++++ icons/wifi.svg | 71 +++++++++++ js/map.js | 117 ++++-------------- js/places.js | 123 ++++++++++++------- js/symbols.js | 204 +++++++++++++++++++++++++++++++ 15 files changed, 599 insertions(+), 190 deletions(-) create mode 100644 icons/default-marker.svg create mode 100644 icons/parking.svg create mode 100644 icons/piscine.svg create mode 100644 icons/wifi.svg create mode 100644 js/symbols.js diff --git a/couches/autogestion.geojson b/couches/autogestion.geojson index c2b7877..cba8f7f 100644 --- a/couches/autogestion.geojson +++ b/couches/autogestion.geojson @@ -4,7 +4,6 @@ "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ { "type": "Feature", "properties": { "name": "Tableau de programmation" }, "geometry": { "type": "Point", "coordinates": [ -2.091304219258237, 47.541608316100941 ] } }, -{ "type": "Feature", "properties": { "name": "Tableau des shifts" }, "geometry": { "type": "Point", "coordinates": [ -2.091287983083753, 47.541680943841193 ] } }, -{ "type": "Feature", "properties": { "name": "Tableau des shifts" }, "geometry": null } +{ "type": "Feature", "properties": { "name": "Tableau des shifts" }, "geometry": { "type": "Point", "coordinates": [ -2.091287983083753, 47.541680943841193 ] } } ] } diff --git a/couches/batiments.geojson b/couches/batiments.geojson index 86550a4..0dd01a7 100644 --- a/couches/batiments.geojson +++ b/couches/batiments.geojson @@ -3,8 +3,8 @@ "name": "batiments", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ -{ "type": "Feature", "properties": { "id": 1, "nom": "Batiment A" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091581996371882, 47.541032945940522 ], [ -2.09151399426637, 47.541497984433285 ], [ -2.091312011285422, 47.541481979469303 ], [ -2.091326034403365, 47.541400730704773 ], [ -2.091241014242576, 47.541394942672135 ], [ -2.091251030755392, 47.541319968658911 ], [ -2.091334848934643, 47.541327974547109 ], [ -2.091346067428997, 47.541254515067628 ], [ -2.091304879528295, 47.541251918559851 ], [ -2.091309046397626, 47.541206046901102 ], [ -2.091353038921917, 47.541207940189693 ], [ -2.091375035184063, 47.541061913344244 ], [ -2.091330882395567, 47.541059965956265 ], [ -2.091335990817103, 47.541026008366721 ], [ -2.091380744596368, 47.54102704967903 ], [ -2.091381966610932, 47.541019003174263 ], [ -2.091581996371882, 47.541032945940522 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 2, "nom": "Batiment B", "electricite-triphase": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091630987136071, 47.541689935433055 ], [ -2.091803321239079, 47.54170457447416 ], [ -2.091796950736927, 47.541739951576218 ], [ -2.092355992350255, 47.541780954364874 ], [ -2.092339965929748, 47.54185403445365 ], [ -2.091958937782201, 47.541822011214833 ], [ -2.09193297498098, 47.54193998862457 ], [ -2.091763976376737, 47.541926005529561 ], [ -2.091756003232534, 47.541964993201951 ], [ -2.091590991200393, 47.541954999486393 ], [ -2.091630987136071, 47.541689935433055 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 10, "nom": "Toilettes sèches" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091342607190285, 47.541484412003662 ], [ -2.091438001950184, 47.541492274863295 ], [ -2.09143324403292, 47.541516949622384 ], [ -2.09133755253389, 47.541508679404679 ], [ -2.091342607190285, 47.541484412003662 ] ] ] ] } } +{ "type": "Feature", "properties": { "id": 1, "nom": "Batiment A", "batiment": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091581996371882, 47.541032945940522 ], [ -2.09151399426637, 47.541497984433285 ], [ -2.091312011285422, 47.541481979469303 ], [ -2.091326034403365, 47.541400730704773 ], [ -2.091241014242576, 47.541394942672135 ], [ -2.091251030755392, 47.541319968658911 ], [ -2.091334848934643, 47.541327974547109 ], [ -2.091346067428997, 47.541254515067628 ], [ -2.091304879528295, 47.541251918559851 ], [ -2.091309046397626, 47.541206046901102 ], [ -2.091353038921917, 47.541207940189693 ], [ -2.091375035184063, 47.541061913344244 ], [ -2.091330882395567, 47.541059965956265 ], [ -2.091335990817103, 47.541026008366721 ], [ -2.091380744596368, 47.54102704967903 ], [ -2.091381966610932, 47.541019003174263 ], [ -2.091581996371882, 47.541032945940522 ] ] ] ] } }, +{ "type": "Feature", "properties": { "id": 2, "nom": "Batiment B", "batiment": true, "electricite-triphase": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091630987136071, 47.541689935433055 ], [ -2.091803321239079, 47.54170457447416 ], [ -2.091796950736927, 47.541739951576218 ], [ -2.092355992350255, 47.541780954364874 ], [ -2.092339965929748, 47.54185403445365 ], [ -2.091958937782201, 47.541822011214833 ], [ -2.09193297498098, 47.54193998862457 ], [ -2.091763976376737, 47.541926005529561 ], [ -2.091756003232534, 47.541964993201951 ], [ -2.091590991200393, 47.541954999486393 ], [ -2.091630987136071, 47.541689935433055 ] ] ] ] } }, +{ "type": "Feature", "properties": { "id": 10, "nom": "Toilettes sèches", "batiment": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091342607190285, 47.541484412003662 ], [ -2.091438001950184, 47.541492274863295 ], [ -2.09143324403292, 47.541516949622384 ], [ -2.09133755253389, 47.541508679404679 ], [ -2.091342607190285, 47.541484412003662 ] ] ] ] } } ] } diff --git a/couches/medic.geojson b/couches/medic.geojson index bca1be1..bfbff26 100644 --- a/couches/medic.geojson +++ b/couches/medic.geojson @@ -3,9 +3,7 @@ "name": "medic", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ -{ "type": "Feature", "properties": { "name": "Infirmerie" }, "geometry": null }, { "type": "Feature", "properties": { "name": "infirmerie" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.091983279274473, 47.541750296814556 ], [ -2.092011290414653, 47.541752703414282 ], [ -2.092017401936146, 47.541713510204964 ], [ -2.091990409382882, 47.54171144740365 ], [ -2.091983279274473, 47.541750296814556 ] ] ] } }, -{ "type": "Feature", "properties": { "name": "infirmerie" }, "geometry": null }, { "type": "Feature", "properties": { "name": "zone infirmerie" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.091842510161106, 47.54181195296588 ], [ -2.091847583778531, 47.541782685155603 ], [ -2.091792696462745, 47.541778014758826 ], [ -2.091786239131476, 47.54180697121209 ], [ -2.091842510161106, 47.54181195296588 ] ] ] } } ] } diff --git a/couches/parkings.geojson b/couches/parkings.geojson index 58f6449..a44e801 100644 --- a/couches/parkings.geojson +++ b/couches/parkings.geojson @@ -6,7 +6,7 @@ { "type": "Feature", "properties": { "Depose-minute": false, "Camping-cars": true, "Parking": true, "capacite": 22 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.092142121259721, 47.542843538132558 ], [ -2.091790408416395, 47.542814759968941 ], [ -2.091825676652254, 47.542523865768402 ], [ -2.092019624006813, 47.542449891415274 ], [ -2.092117032543631, 47.542463394677995 ], [ -2.092187417610755, 47.542510789651068 ], [ -2.092187417610755, 47.542577339516328 ], [ -2.092190082101993, 47.542645687938666 ], [ -2.092142121259721, 47.542843538132558 ] ] ] } }, { "type": "Feature", "properties": { "Depose-minute": true, "Camping-cars": false, "Parking": true, "capacite": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.091743572922097, 47.541980542375086 ], [ -2.091739874320352, 47.542006758143337 ], [ -2.091580834445331, 47.541998019555379 ], [ -2.091584533047075, 47.541970555412306 ], [ -2.091743572922097, 47.541980542375086 ] ] ] } }, { "type": "Feature", "properties": { "Depose-minute": false, "Camping-cars": true, "Parking": true, "capacite": 40 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.09169087019505, 47.542803910588248 ], [ -2.09105629017985, 47.542748503711742 ], [ -2.09112010389859, 47.542425620241325 ], [ -2.091718701205569, 47.542495685076233 ], [ -2.09169087019505, 47.542803910588248 ] ] ] } }, -{ "type": "Feature", "properties": { "Depose-minute": true, "Camping-cars": false, "Parking": false, "capacite": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.092222541848034, 47.541986784225863 ], [ -2.092189254432332, 47.541949333110082 ], [ -2.092100487990459, 47.542003013034389 ], [ -2.092155967016629, 47.542029228791392 ], [ -2.092222541848034, 47.541986784225863 ] ] ] } }, +{ "type": "Feature", "properties": { "Depose-minute": true, "Camping-cars": false, "Parking": true, "capacite": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.092222541848034, 47.541986784225863 ], [ -2.092189254432332, 47.541949333110082 ], [ -2.092100487990459, 47.542003013034389 ], [ -2.092155967016629, 47.542029228791392 ], [ -2.092222541848034, 47.541986784225863 ] ] ] } }, { "type": "Feature", "properties": { "Depose-minute": false, "Camping-cars": false, "Parking": true, "capacite": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.078307269873994, 47.546685973108467 ], [ -2.07816210937131, 47.546686855827154 ], [ -2.07813987758261, 47.546558861460824 ], [ -2.078307269873994, 47.546685973108467 ] ] ] } }, { "type": "Feature", "properties": { "Depose-minute": false, "Camping-cars": false, "Parking": true, "capacite": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.07811429061191, 47.548355153984389 ], [ -2.078164577560365, 47.548179272065255 ], [ -2.077769139283883, 47.548093645127835 ], [ -2.077535990704686, 47.548346668466756 ], [ -2.078101718874796, 47.548412238340063 ], [ -2.07811429061191, 47.548355153984389 ] ] ] } }, { "type": "Feature", "properties": { "Depose-minute": false, "Camping-cars": false, "Parking": true, "capacite": 40 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.079644526778333, 47.549831784523974 ], [ -2.079205275991393, 47.549965674823767 ], [ -2.078969119654329, 47.549651669652548 ], [ -2.07941309356801, 47.549500245166655 ], [ -2.079644526778333, 47.549831784523974 ] ] ] } }, diff --git a/couches/pieces-batiments.geojson b/couches/pieces-batiments.geojson index 7ffe66d..86a60c7 100644 --- a/couches/pieces-batiments.geojson +++ b/couches/pieces-batiments.geojson @@ -3,30 +3,30 @@ "name": "pieces-batiments", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ -{ "type": "Feature", "properties": { "id": 1, "name": "Salle à manger", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091803344599751, 47.541704589719863 ], [ -2.091772833474595, 47.541875987459946 ], [ -2.091696968797553, 47.541870845299627 ], [ -2.091703022024791, 47.54183458014915 ], [ -2.091610059534208, 47.541828751805809 ], [ -2.091631027818287, 47.541690028656284 ], [ -2.091803344599751, 47.541704589719863 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 2, "name": "Cuisine", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091720961698117, 47.541872552348394 ], [ -2.09171563094476, 47.541910422595102 ], [ -2.091765708928661, 47.541914819548275 ], [ -2.091755963116424, 47.541965037290019 ], [ -2.091591105232199, 47.541954952052144 ], [ -2.091610190850896, 47.54182878845991 ], [ -2.091702972058417, 47.541834623206363 ], [ -2.091697048172613, 47.541870855925914 ], [ -2.091720961698117, 47.541872552348394 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 3, "name": "Toilettes", "toilettes": true, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091772751762869, 47.541876028605977 ], [ -2.091765717111395, 47.541914830245268 ], [ -2.091715628651217, 47.541910327403237 ], [ -2.091721086231624, 47.541872503515016 ], [ -2.091772751762869, 47.541876028605977 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 4, "name": "Salle polyvalente", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091784815278911, 47.541808214080078 ], [ -2.091958992911517, 47.541822034555537 ], [ -2.091933044939367, 47.541940064093374 ], [ -2.091763691017441, 47.541925910319492 ], [ -2.091784815278911, 47.541808214080078 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 5, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091958992251015, 47.541822034555537 ], [ -2.091844168369957, 47.541812636999211 ], [ -2.091856286723147, 47.541743668891101 ], [ -2.09197028936854, 47.541752404530854 ], [ -2.091958992251015, 47.541822034555537 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 7, "name": "Réserve", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091844009103773, 47.541812895270205 ], [ -2.091784870648028, 47.541808209316194 ], [ -2.09179050735358, 47.541776654559868 ], [ -2.091849600044912, 47.541781056139008 ], [ -2.091844009103773, 47.541812895270205 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 8, "name": "Aile ouest", "toilettes": false, "n couchage": null, "douches": false, "pmr": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091958998067715, 47.54182199973912 ], [ -2.09197030240704, 47.541752350898967 ], [ -2.092355993668751, 47.541780997009639 ], [ -2.092339993158979, 47.541853997664646 ], [ -2.091958998067715, 47.54182199973912 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 9, "name": "Régie", "toilettes": false, "n couchage": null, "douches": false, "pmr": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091797061088745, 47.541739907554394 ], [ -2.091856210245345, 47.541743887914542 ], [ -2.091849729126421, 47.541781097436456 ], [ -2.091790540676175, 47.541776654559868 ], [ -2.091797061088745, 47.541739907554394 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 10, "name": "Dortoir", "toilettes": false, "n couchage": 9, "douches": false, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091513984486493, 47.541497970679082 ], [ -2.091312031318447, 47.541481871281974 ], [ -2.091319563736084, 47.541437298073781 ], [ -2.091355282240157, 47.541440556482534 ], [ -2.091357636451076, 47.541425832768645 ], [ -2.091496188687846, 47.541437050836741 ], [ -2.091494042201419, 47.5414527093861 ], [ -2.091520284729023, 47.541454859514907 ], [ -2.091513984486493, 47.541497970679082 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 11, "name": "Dortoiran", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091496186962639, 47.54143705074641 ], [ -2.091357636065354, 47.54142583034475 ], [ -2.091365923131042, 47.541367825645708 ], [ -2.091531068219536, 47.541381078109474 ], [ -2.091525142027638, 47.541421687499131 ], [ -2.091498726214174, 47.541419858360889 ], [ -2.091496186962639, 47.54143705074641 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 12, "name": "Dortoirhin", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091531100751232, 47.541381082186092 ], [ -2.091365924459619, 47.541367822129459 ], [ -2.091374658392441, 47.541309434176171 ], [ -2.091512809971881, 47.541320692823099 ], [ -2.091510629056958, 47.541337809818359 ], [ -2.091537037797344, 47.541340343423826 ], [ -2.091531100751232, 47.541381082186092 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 15, "name": "DORTOUER !", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091547712938505, 47.54126725655756 ], [ -2.091383061098264, 47.541253868718748 ], [ -2.091390628898466, 47.541202709369138 ], [ -2.091527068817096, 47.541212684131487 ], [ -2.09152545827858, 47.541225814277354 ], [ -2.091553444836405, 47.541228132701661 ], [ -2.091547712938505, 47.54126725655756 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 14, "name": "DORTOUAR !", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091512807891281, 47.541320684413535 ], [ -2.091374658571692, 47.541309434463415 ], [ -2.09138306108793, 47.541253869055801 ], [ -2.091547708479571, 47.541267252701118 ], [ -2.091541890653248, 47.541307116745308 ], [ -2.0915149636497, 47.541304886367087 ], [ -2.091512807891281, 47.541320684413535 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 15, "name": "Dortoir ?", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091527068279477, 47.541212688576692 ], [ -2.091390628731268, 47.541202706216346 ], [ -2.091398039743798, 47.541151059604289 ], [ -2.09153491127021, 47.54116080588124 ], [ -2.091535469734013, 47.541157821323246 ], [ -2.091563439462842, 47.541159831972855 ], [ -2.091558234933273, 47.541195415654116 ], [ -2.091530061605953, 47.541193542936504 ], [ -2.091527068279477, 47.541212688576692 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 17, "name": "S.A.N.", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091569174874294, 47.541120597227135 ], [ -2.091519673666023, 47.54111719870663 ], [ -2.091484634757828, 47.541114715735404 ], [ -2.091497522553489, 47.541027037904492 ], [ -2.091581989558546, 47.541032936151403 ], [ -2.091569174874294, 47.541120597227135 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 18, "name": null, "toilettes": false, "n couchage": 0, "douches": true, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091497441875379, 47.541027061687174 ], [ -2.091486517145593, 47.541102092039424 ], [ -2.091370407902545, 47.541094109203854 ], [ -2.091381988141875, 47.541018994879494 ], [ -2.091497441875379, 47.541027061687174 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 19, "name": null, "toilettes": true, "n couchage": 0, "douches": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091325974304333, 47.541400816916251 ], [ -2.091240947788481, 47.541395030318668 ], [ -2.091250983313784, 47.541320011014868 ], [ -2.091334975801904, 47.541328017529352 ], [ -2.091325974304333, 47.541400816916251 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 20, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091519659708729, 47.541117199369673 ], [ -2.091517504484667, 47.541131244918141 ], [ -2.091401944662798, 47.541123124722198 ], [ -2.091355283309725, 47.54144055539323 ], [ -2.091319563736084, 47.541437298073781 ], [ -2.091325894172231, 47.541401168525681 ], [ -2.091334953198116, 47.541327997150162 ], [ -2.091370372463667, 47.541093963571548 ], [ -2.091486449400059, 47.541102080066366 ], [ -2.091484630455735, 47.541114714816082 ], [ -2.091519659708729, 47.541117199369673 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 21, "name": "S.A.N.", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091346050044288, 47.541254629515471 ], [ -2.091305020991117, 47.54125195944119 ], [ -2.091308995388566, 47.541206066134919 ], [ -2.091353136397722, 47.541208003574475 ], [ -2.091346050044288, 47.541254629515471 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 22, "name": "Fioul", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091335973355576, 47.541025992012997 ], [ -2.091380782392617, 47.541027051620048 ], [ -2.091374991976149, 47.541061999910184 ], [ -2.091331000086885, 47.541060000059225 ], [ -2.091335973355576, 47.541025992012997 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 24, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091553465453023, 47.54122812760788 ], [ -2.091525455304059, 47.541225810566047 ], [ -2.091530065826963, 47.54119354580304 ], [ -2.091558244276249, 47.541195410738212 ], [ -2.091553465453023, 47.54122812760788 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 24, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091537053394358, 47.541340342066142 ], [ -2.09151062838619, 47.541337807354552 ], [ -2.091514970769075, 47.541304871284794 ], [ -2.091541897498958, 47.541307121053045 ], [ -2.091537053394358, 47.541340342066142 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 25, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091520309291041, 47.541454859428924 ], [ -2.091494041971326, 47.541452709231201 ], [ -2.091498730491986, 47.54141986300997 ], [ -2.091525159923799, 47.541421689054665 ], [ -2.091520309291041, 47.541454859428924 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 30, "name": "Toilettes sèches", "toilettes": true, "n couchage": 0, "douches": false, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.0914328905057, 47.54151697382953 ], [ -2.091337448370911, 47.541508740538298 ], [ -2.091342288235758, 47.541484563405774 ], [ -2.091437923965141, 47.541492273951967 ], [ -2.0914328905057, 47.54151697382953 ] ] ] ] } }, -{ "type": "Feature", "properties": { "id": 999, "name": "Trésor ???", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091084999999803, 47.54062200000012 ], [ -2.091044000329997, 47.540618999547782 ], [ -2.091051001856652, 47.540575000998821 ], [ -2.091096001550976, 47.540576997695652 ], [ -2.091084999999803, 47.54062200000012 ] ] ] ] } } +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 1, "name": "Salle à manger", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091803344599751, 47.541704589719863 ], [ -2.091772833474595, 47.541875987459946 ], [ -2.091696968797553, 47.541870845299627 ], [ -2.091703022024791, 47.54183458014915 ], [ -2.091610059534208, 47.541828751805809 ], [ -2.091631027818287, 47.541690028656284 ], [ -2.091803344599751, 47.541704589719863 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 2, "name": "Cuisine", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091720961698117, 47.541872552348394 ], [ -2.09171563094476, 47.541910422595102 ], [ -2.091765708928661, 47.541914819548275 ], [ -2.091755963116424, 47.541965037290019 ], [ -2.091591105232199, 47.541954952052144 ], [ -2.091610190850896, 47.54182878845991 ], [ -2.091702972058417, 47.541834623206363 ], [ -2.091697048172613, 47.541870855925914 ], [ -2.091720961698117, 47.541872552348394 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 3, "name": "Toilettes", "toilettes": true, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091772751762869, 47.541876028605977 ], [ -2.091765717111395, 47.541914830245268 ], [ -2.091715628651217, 47.541910327403237 ], [ -2.091721086231624, 47.541872503515016 ], [ -2.091772751762869, 47.541876028605977 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 4, "name": "Salle polyvalente", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091784815278911, 47.541808214080078 ], [ -2.091958992911517, 47.541822034555537 ], [ -2.091933044939367, 47.541940064093374 ], [ -2.091763691017441, 47.541925910319492 ], [ -2.091784815278911, 47.541808214080078 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 5, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091958992251015, 47.541822034555537 ], [ -2.091844168369957, 47.541812636999211 ], [ -2.091856286723147, 47.541743668891101 ], [ -2.09197028936854, 47.541752404530854 ], [ -2.091958992251015, 47.541822034555537 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 7, "name": "Réserve", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091844009103773, 47.541812895270205 ], [ -2.091784870648028, 47.541808209316194 ], [ -2.09179050735358, 47.541776654559868 ], [ -2.091849600044912, 47.541781056139008 ], [ -2.091844009103773, 47.541812895270205 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 8, "name": "Aile ouest", "toilettes": false, "n couchage": null, "douches": false, "pmr": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091958998067715, 47.54182199973912 ], [ -2.09197030240704, 47.541752350898967 ], [ -2.092355993668751, 47.541780997009639 ], [ -2.092339993158979, 47.541853997664646 ], [ -2.091958998067715, 47.54182199973912 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 9, "name": "Régie", "toilettes": false, "n couchage": null, "douches": false, "pmr": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091797061088745, 47.541739907554394 ], [ -2.091856210245345, 47.541743887914542 ], [ -2.091849729126421, 47.541781097436456 ], [ -2.091790540676175, 47.541776654559868 ], [ -2.091797061088745, 47.541739907554394 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 10, "name": "Dortoir", "toilettes": false, "n couchage": 9, "douches": false, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091513984486493, 47.541497970679082 ], [ -2.091312031318447, 47.541481871281974 ], [ -2.091319563736084, 47.541437298073781 ], [ -2.091355282240157, 47.541440556482534 ], [ -2.091357636451076, 47.541425832768645 ], [ -2.091496188687846, 47.541437050836741 ], [ -2.091494042201419, 47.5414527093861 ], [ -2.091520284729023, 47.541454859514907 ], [ -2.091513984486493, 47.541497970679082 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 11, "name": "Dortoiran", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091496186962639, 47.54143705074641 ], [ -2.091357636065354, 47.54142583034475 ], [ -2.091365923131042, 47.541367825645708 ], [ -2.091531068219536, 47.541381078109474 ], [ -2.091525142027638, 47.541421687499131 ], [ -2.091498726214174, 47.541419858360889 ], [ -2.091496186962639, 47.54143705074641 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 12, "name": "Dortoirhin", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091531100751232, 47.541381082186092 ], [ -2.091365924459619, 47.541367822129459 ], [ -2.091374658392441, 47.541309434176171 ], [ -2.091512809971881, 47.541320692823099 ], [ -2.091510629056958, 47.541337809818359 ], [ -2.091537037797344, 47.541340343423826 ], [ -2.091531100751232, 47.541381082186092 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 15, "name": "DORTOUER !", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091547712938505, 47.54126725655756 ], [ -2.091383061098264, 47.541253868718748 ], [ -2.091390628898466, 47.541202709369138 ], [ -2.091527068817096, 47.541212684131487 ], [ -2.09152545827858, 47.541225814277354 ], [ -2.091553444836405, 47.541228132701661 ], [ -2.091547712938505, 47.54126725655756 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 14, "name": "DORTOUAR !", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091512807891281, 47.541320684413535 ], [ -2.091374658571692, 47.541309434463415 ], [ -2.09138306108793, 47.541253869055801 ], [ -2.091547708479571, 47.541267252701118 ], [ -2.091541890653248, 47.541307116745308 ], [ -2.0915149636497, 47.541304886367087 ], [ -2.091512807891281, 47.541320684413535 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 15, "name": "Dortoir ?", "toilettes": false, "n couchage": 9, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091527068279477, 47.541212688576692 ], [ -2.091390628731268, 47.541202706216346 ], [ -2.091398039743798, 47.541151059604289 ], [ -2.09153491127021, 47.54116080588124 ], [ -2.091535469734013, 47.541157821323246 ], [ -2.091563439462842, 47.541159831972855 ], [ -2.091558234933273, 47.541195415654116 ], [ -2.091530061605953, 47.541193542936504 ], [ -2.091527068279477, 47.541212688576692 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 17, "name": "S.A.N.", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091569174874294, 47.541120597227135 ], [ -2.091519673666023, 47.54111719870663 ], [ -2.091484634757828, 47.541114715735404 ], [ -2.091497522553489, 47.541027037904492 ], [ -2.091581989558546, 47.541032936151403 ], [ -2.091569174874294, 47.541120597227135 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 18, "name": null, "toilettes": false, "n couchage": 0, "douches": true, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091497441875379, 47.541027061687174 ], [ -2.091486517145593, 47.541102092039424 ], [ -2.091370407902545, 47.541094109203854 ], [ -2.091381988141875, 47.541018994879494 ], [ -2.091497441875379, 47.541027061687174 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 19, "name": null, "toilettes": true, "n couchage": 0, "douches": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091325974304333, 47.541400816916251 ], [ -2.091240947788481, 47.541395030318668 ], [ -2.091250983313784, 47.541320011014868 ], [ -2.091334975801904, 47.541328017529352 ], [ -2.091325974304333, 47.541400816916251 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 20, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091519659708729, 47.541117199369673 ], [ -2.091517504484667, 47.541131244918141 ], [ -2.091401944662798, 47.541123124722198 ], [ -2.091355283309725, 47.54144055539323 ], [ -2.091319563736084, 47.541437298073781 ], [ -2.091325894172231, 47.541401168525681 ], [ -2.091334953198116, 47.541327997150162 ], [ -2.091370372463667, 47.541093963571548 ], [ -2.091486449400059, 47.541102080066366 ], [ -2.091484630455735, 47.541114714816082 ], [ -2.091519659708729, 47.541117199369673 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 21, "name": "S.A.N.", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091346050044288, 47.541254629515471 ], [ -2.091305020991117, 47.54125195944119 ], [ -2.091308995388566, 47.541206066134919 ], [ -2.091353136397722, 47.541208003574475 ], [ -2.091346050044288, 47.541254629515471 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 22, "name": "Fioul", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091335973355576, 47.541025992012997 ], [ -2.091380782392617, 47.541027051620048 ], [ -2.091374991976149, 47.541061999910184 ], [ -2.091331000086885, 47.541060000059225 ], [ -2.091335973355576, 47.541025992012997 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 24, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091553465453023, 47.54122812760788 ], [ -2.091525455304059, 47.541225810566047 ], [ -2.091530065826963, 47.54119354580304 ], [ -2.091558244276249, 47.541195410738212 ], [ -2.091553465453023, 47.54122812760788 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 24, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091537053394358, 47.541340342066142 ], [ -2.09151062838619, 47.541337807354552 ], [ -2.091514970769075, 47.541304871284794 ], [ -2.091541897498958, 47.541307121053045 ], [ -2.091537053394358, 47.541340342066142 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 25, "name": null, "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091520309291041, 47.541454859428924 ], [ -2.091494041971326, 47.541452709231201 ], [ -2.091498730491986, 47.54141986300997 ], [ -2.091525159923799, 47.541421689054665 ], [ -2.091520309291041, 47.541454859428924 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 30, "name": "Toilettes sèches", "toilettes": true, "n couchage": 0, "douches": false, "pmr": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.0914328905057, 47.54151697382953 ], [ -2.091337448370911, 47.541508740538298 ], [ -2.091342288235758, 47.541484563405774 ], [ -2.091437923965141, 47.541492273951967 ], [ -2.0914328905057, 47.54151697382953 ] ] ] ] } }, +{ "type": "Feature", "properties": { "piece-batiment": true, "id": 999, "name": "Trésor ???", "toilettes": false, "n couchage": null, "douches": false }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091084999999803, 47.54062200000012 ], [ -2.091044000329997, 47.540618999547782 ], [ -2.091051001856652, 47.540575000998821 ], [ -2.091096001550976, 47.540576997695652 ], [ -2.091084999999803, 47.54062200000012 ] ] ] ] } } ] } diff --git a/couches/piscine.geojson b/couches/piscine.geojson index 291a8ea..924ca7d 100644 --- a/couches/piscine.geojson +++ b/couches/piscine.geojson @@ -3,6 +3,6 @@ "name": "piscine", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ -{ "type": "Feature", "properties": { "id": null, "name": "Piscine" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091707042517393, 47.542115661078718 ], [ -2.091903846960937, 47.542128643402442 ], [ -2.091884615256356, 47.542248080629903 ], [ -2.091687810812811, 47.542235963822122 ], [ -2.091707042517393, 47.542115661078718 ] ] ] ] } } +{ "type": "Feature", "properties": { "id": null, "name": "Piscine", "piscine": true }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -2.091707042517393, 47.542115661078718 ], [ -2.091903846960937, 47.542128643402442 ], [ -2.091884615256356, 47.542248080629903 ], [ -2.091687810812811, 47.542235963822122 ], [ -2.091707042517393, 47.542115661078718 ] ] ] ] } } ] } diff --git a/couches/wifi.geojson b/couches/wifi.geojson index ea0ef34..8476f2f 100644 --- a/couches/wifi.geojson +++ b/couches/wifi.geojson @@ -3,8 +3,8 @@ "name": "wifi", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ -{ "type": "Feature", "properties": { "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.091875157168781, 47.541822388950891 ] } }, -{ "type": "Feature", "properties": { "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.091771851987061, 47.541790332713326 ] } }, -{ "type": "Feature", "properties": { "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.092165078162641, 47.541781334467679 ] } } +{ "type": "Feature", "properties": { "wifi": true, "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.091875157168781, 47.541822388950891 ] } }, +{ "type": "Feature", "properties": { "wifi": true, "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.091771851987061, 47.541790332713326 ] } }, +{ "type": "Feature", "properties": { "wifi": true, "fixe": true }, "geometry": { "type": "Point", "coordinates": [ -2.092165078162641, 47.541781334467679 ] } } ] } diff --git a/css/style.css b/css/style.css index cba1aa4..7794b4f 100644 --- a/css/style.css +++ b/css/style.css @@ -71,22 +71,8 @@ body > * { } } -.map-hilight-area.active { - stroke: #ff4e00; - stroke-width: 5px; - fill: rgba(255, 77, 0, 0.25); -} - -.highlight-point-icon::after { - content: ""; - width: 5px; - height: 5px; - border-radius: 100%; - background: transparent; -} - -.active .highlight-point-icon::after { - background: #ff4e00; +.highlight-point-icon > * { + transform: translateX(-50%) translateY(-50%); } .map-amenity-icon .map-amenity-icon-container { diff --git a/icons/default-marker.svg b/icons/default-marker.svg new file mode 100644 index 0000000..ffe0405 --- /dev/null +++ b/icons/default-marker.svg @@ -0,0 +1,48 @@ + + + + + + + + + + diff --git a/icons/parking.svg b/icons/parking.svg new file mode 100644 index 0000000..ec261d4 --- /dev/null +++ b/icons/parking.svg @@ -0,0 +1,66 @@ + + + +P diff --git a/icons/piscine.svg b/icons/piscine.svg new file mode 100644 index 0000000..ecff3e1 --- /dev/null +++ b/icons/piscine.svg @@ -0,0 +1,71 @@ + + + + diff --git a/icons/wifi.svg b/icons/wifi.svg new file mode 100644 index 0000000..7d02eae --- /dev/null +++ b/icons/wifi.svg @@ -0,0 +1,71 @@ + + + + diff --git a/js/map.js b/js/map.js index c8a18f9..439048d 100644 --- a/js/map.js +++ b/js/map.js @@ -1,5 +1,5 @@ import * as L from "./lib/leaflet/leaflet-src.esm.js" -import { PlaceDatabase } from "./places.js"; +import { MapSubFeature, PlaceDatabase } from "./places.js"; import "./lib/turf/turf.js" let map = null; @@ -93,93 +93,43 @@ export async function init(){ const HIGHLIGHT_LAYER = Symbol("Highlight map layer") const AMENITY_MARKER_LAYER = Symbol("Amenity marker layer") const PARENT_FEATURE = Symbol("Parent feature") -const HIGHLIGHT_MARKER_ICON = L.divIcon({ - className: "highlight-point-icon" -}) export async function init_places(places_db){ places = places_db - - // La couche des zones disponibles - const amenities = L.geoJSON(null, { - pointToLayer: function(feature, latlng) { - let iconEl = document.createElement("div") - iconEl.classList.add("map-amenity-icon-container") - - if(feature.properties["eau potable"]){ - let drinking_water_icon = document.createElement("img") - drinking_water_icon.src = new URL("../icons/eau-potable.svg", import.meta.url).toString() - drinking_water_icon.alt = "Icone d'une goute" - drinking_water_icon.title = "Eau potable" - drinking_water_icon.classList.add("drinking-water") - iconEl.append(drinking_water_icon) - } - - if(feature.properties["toilettes"]){ - let bathrooms_icon = document.createElement("img") - bathrooms_icon.src = new URL("../icons/toilettes.svg", import.meta.url).toString() - bathrooms_icon.alt = "Icone de toilettes" - bathrooms_icon.title = "Toilettes" - bathrooms_icon.classList.add("bathroom") - iconEl.append(bathrooms_icon) - } - - if(feature.properties["douches"]){ - let shower_icon = document.createElement("img") - shower_icon.src = new URL("../icons/douches.svg", import.meta.url).toString() - shower_icon.alt = "Icone de douche" - shower_icon.title = "Douches" - shower_icon.classList.add("shower") - iconEl.append(shower_icon) - } - - if(feature.properties["n couchage"]){ - let dorm_icon = document.createElement("img") - dorm_icon.src = new URL("../icons/dortoir.svg", import.meta.url).toString() - dorm_icon.alt = "Icone de dortoir" - dorm_icon.title = "Dortoir" - dorm_icon.classList.add("dorm") - iconEl.append(dorm_icon) - } - - let icon = L.divIcon({ - className: "map-amenity-icon", - html: iconEl - }) - - return L.marker(latlng, { - icon: icon - }) - }, - onEachFeature: function(feature, layer){ - if(feature[PARENT_FEATURE]){ - feature[PARENT_FEATURE][AMENITY_MARKER_LAYER] = layer - } else { - feature[AMENITY_MARKER_LAYER] = layer - } - } - }).addTo(map) // La couche des zones disponibles const area_highlight = L.geoJSON(null, { pointToLayer: function(feature, latlng) { - return L.marker(latlng, { - icon: HIGHLIGHT_MARKER_ICON - }) + let symbol = feature.mapSymbol; + if(symbol.markerUrl) { + + let iconEl = document.createElement("img"); + iconEl.src = symbol.markerUrl; + + if(iconEl){ + return L.marker(latlng, { + icon: L.divIcon({ + className: "highlight-point-icon", + html: iconEl, + iconSize: [0, 0] + }) + }) + } + } }, style: function(feature){ + let symbol = feature.mapSymbol; return { className: "map-hilight-area", - fill: false, - stroke: false + fill: !!symbol.backgroundColor, + fillColor: symbol.backgroundColor, + fillOpacity: 0.5, + stroke: !!symbol.borderColor, + color: symbol.borderColor, } }, onEachFeature: function(feature, layer){ - if(feature[PARENT_FEATURE]){ - feature[PARENT_FEATURE][HIGHLIGHT_LAYER] = layer - } else { - feature[HIGHLIGHT_LAYER] = layer - } + feature[HIGHLIGHT_LAYER] = layer } }).addTo(map) @@ -187,22 +137,9 @@ export async function init_places(places_db){ for(let [_feature_id, feature] of Object.entries(places.featuresById)){ area_highlight.addData(feature) - if(feature.properties["toilettes"] - || feature.properties["douches"] - || feature.properties["eau potable"] - || feature.properties["n couchage"] - ) { - let amenity_feature - - if(feature.geometry.type != "Point"){ - amenity_feature = turf.centerOfMass(feature) - amenity_feature[PARENT_FEATURE] = feature - amenity_feature.properties = feature.properties - } else { - amenity_feature = feature - } - - amenities.addData(amenity_feature) + let point_feature = feature.asPoint() + if(point_feature !== feature){ + area_highlight.addData(point_feature) } } } diff --git a/js/places.js b/js/places.js index 43d1cee..aebbb17 100644 --- a/js/places.js +++ b/js/places.js @@ -1,10 +1,11 @@ import lunr from "./lib/lunr/lunr.js" import lunrStemmer from "./lib/lunr/lunr.stemmer.support.js" import lunrFr from "./lib/lunr/lunr.fr.js" +import { MapSymbol } from "./symbols.js" lunrStemmer(lunr) lunrFr(lunr) -const FEATURE_I = Symbol("Feature index") +const FEATURE_INDEX = Symbol("Feature index") export const FEATURE_ID = Symbol("Feature id") /** @@ -92,22 +93,29 @@ export class PlaceDatabase extends EventTarget { let all_ids = [] if(geojson.type == "Feature"){ - let featureId = geojson?.properties?.id || geojson?.properties?.[FEATURE_I] - let full_id = idPrefix+"#"+featureId - if(this.featuresById[full_id]){ - console.warn(`Warning: a feature with ID "${full_id}" already exists in database`) + let feature = geojson; + if(!(feature instanceof MapFeature)){ + feature = new MapFeature(geojson) } - geojson[FEATURE_ID] = full_id - this.featuresById[full_id] = geojson + if(!feature.id){ + let full_id = idPrefix+"#"+(geojson?.properties?.id || geojson?.properties?.[FEATURE_INDEX]) + feature.id = full_id + } + + if(this.featuresById[feature.id]){ + console.warn(`Warning: a feature with ID "${feature.id}" already exists in database`) + } + + this.featuresById[feature.id] = feature let event = new Event("newfeature") - event.ref = full_id - event.feature = geojson + event.ref = feature.id + event.feature = feature this.dispatchEvent(event) - all_ids.push(full_id) + all_ids.push(feature.id) } else if(geojson.type == "FeatureCollection") { @@ -115,15 +123,15 @@ export class PlaceDatabase extends EventTarget { idPrefix += (idPrefix != "" ? "-" : "")+geojson.name } - if(geojson?.properties?.[FEATURE_I]){ - idPrefix += (idPrefix != "" ? "-" : "")+geojson.properties[FEATURE_I] + if(geojson?.properties?.[FEATURE_INDEX]){ + idPrefix += (idPrefix != "" ? "-" : "")+geojson.properties[FEATURE_INDEX] } for(let [i, feature] of Object.entries(geojson.features)){ feature.properties = { ...(feature.properties || {}), - [FEATURE_I]: i + [FEATURE_INDEX]: i } let id = this.addFeature(feature, { @@ -159,19 +167,21 @@ export class PlaceDatabase extends EventTarget { this.field("synonyms") for(let [id, feature] of Object.entries(database.featuresById)){ - let synonyms = "" + let sym = feature.mapSymbol; - if(feature.properties["n couchage"] > 0){ - synonyms += SLEEPING_SYNONYMS.join(" ") + let synonyms = [] + + if(sym.genericName){ + synonyms.push(sym.genericName) } - if(feature.properties["toilettes"]){ - synonyms += " "+TOILETTES_SYNONYMS.join(" ") + if(sym.indexSynonyms){ + synonyms.push(...sym.indexSynonyms) } this.add({ id, - name: feature.properties.name, + name: feature.properties.name || sym.genericName, synonyms }) } @@ -213,32 +223,51 @@ export class PlaceDatabase extends EventTarget { } -const SLEEPING_SYNONYMS = [ - "dodo", - "dortoir", - "mimir", - "dormir", - "lit" -] +const POINT_FEATURE = Symbol("Point feature") -const TOILETTES_SYNONYMS = [ - "caca", - "pipi", - "cabinets", - "water-closet", - "latrines", - "🚽", - "double véssé", - "chaise percée", - "WC", - "waters", - "toilettes", - "toilette", - "chiotte", - "chiottes", - "le trône", - "le trones", - "pièce mystère", - "backroom", - "retailleau" -] +export class MapFeature { + constructor(geojson){ + Object.assign(this, geojson) + } + + get id(){ + return this[FEATURE_ID] + } + + set id(value){ + this[FEATURE_ID] = value + } + + get mapSymbol(){ + return MapSymbol.fromFeature(this) + } + + asPoint(){ + if(!this[POINT_FEATURE]){ + if(!this.geometry){ + debugger; + } + if(this.geometry.type != "Point"){ + let point_feature = turf.centerOfMass(this) + point_feature.properties = this.properties + point_feature = new MapSubFeature(point_feature, this) + this[POINT_FEATURE] = point_feature + } else { + this[POINT_FEATURE] = this + } + } + return this[POINT_FEATURE] + } +} + +const PARENT_FEATURE = Symbol("Parent feature") +export class MapSubFeature extends MapFeature { + constructor(geojson, parent){ + super(geojson) + this[PARENT_FEATURE] = parent + } + + get parentFeature(){ + return this[PARENT_FEATURE] + } +} diff --git a/js/symbols.js b/js/symbols.js new file mode 100644 index 0000000..310a506 --- /dev/null +++ b/js/symbols.js @@ -0,0 +1,204 @@ +import { MapFeature } from "./places.js" + +export class MapSymbol { + + /** + * Solid background color of this area (if any) + * @type {undefined|string} + */ + backgroundColor = undefined + + /** + * Background raster tiled image to put on top of solid background (if any) + * @type {undefined|string|URL} + */ + backgroundUrl = undefined + + /** + * Border color of area (if any) + * @type {undefined|string} + */ + borderColor = undefined + + /** + * Marker URL to place on feature (if point) or on centroid (if area) + * @type {undefined|string|URL} + */ + markerUrl = undefined + + /** + * Generic name of this feature if no more precise name is given + * @type {undefined|string} + */ + genericName = undefined + + /** + * A list of sysnonyms for this feature for full text indexing + * @type {string[]} + */ + indexSynonyms = [] + + clone(){ + let new_symb = new MapSymbol() + Object.assign(new_symb, this) + return new_symb + } + + static fromFeature(feature){ + return getSymbolForFeature(feature) + } +} + +/** + * Get a map symbol from feature properties + * @param {MapFeature|Object} feature + */ +function getSymbolForFeature(feature){ + let sym = getBaseSymbolForFeature(feature); + + if(feature.properties["color"]){ + sym = sym.clone() + sym.backgroundColor = feature.properties["color"] + sym.borderColor = feature.properties["color"] + } + + return sym +} + +function getBaseSymbolForFeature(feature){ + + if(feature.properties["wifi"]){ + return WIFI_SYMBOL + } + + if(feature.properties["zone-interdite"]){ + return VERBOTEN_AREA_SYMBOL + } + + if(feature.properties["piscine"]){ + return SWIMMING_POOL_SYMBOL + } + + if(feature.properties["Parking"]){ + return PARKING_SYMBOL + } + + if(feature.properties["n couchage"] > 0){ + return SLEEPING_SYMBOL + } + + if(feature.properties["toilettes"]){ + return TOILETS_SYMBOL + } + + if(feature.properties["douches"]){ + return SHOWER_SYMBOL + } + + if(feature.properties["eau potable"]){ + return DRINKING_WATER_SYMBOL + } + + if(feature.properties["batiment"] || feature.properties["piece-batiment"]){ + return BUILDING_SYMBOL + } + + return DEFAULT_SYMBOL +} + +// PREDEFINED Symbols + +export const DEFAULT_SYMBOL = new MapSymbol() +{ + DEFAULT_SYMBOL.markerUrl = new URL("../icons/default-marker.svg", import.meta.url) + DEFAULT_SYMBOL.backgroundColor = "white" + DEFAULT_SYMBOL.borderColor = "white" +} + +export const SLEEPING_SYMBOL = new MapSymbol() +{ + SLEEPING_SYMBOL.markerUrl = new URL("../icons/dortoir.svg", import.meta.url) + SLEEPING_SYMBOL.genericName = "Dortoir" + SLEEPING_SYMBOL.indexSynonyms = [ + "dodo", + "dortoir", + "mimir", + "dormir", + "lit" + ] +} + +export const DRINKING_WATER_SYMBOL = new MapSymbol() +{ + DRINKING_WATER_SYMBOL.markerUrl = new URL("../icons/eau-potable.svg", import.meta.url) + DRINKING_WATER_SYMBOL.genericName = "Point d'eau potable" +} + +export const PARKING_SYMBOL = new MapSymbol() +{ + PARKING_SYMBOL.markerUrl = new URL("../icons/parking.svg", import.meta.url) + PARKING_SYMBOL.genericName = "Parking" + PARKING_SYMBOL.backgroundColor = "#2d2d2d" + PARKING_SYMBOL.borderColor = "#989898" +} + +export const TOILETS_SYMBOL = new MapSymbol() +{ + TOILETS_SYMBOL.markerUrl = new URL("../icons/toilettes.svg", import.meta.url) + TOILETS_SYMBOL.genericName = "Toilettes" + TOILETS_SYMBOL.indexSynonyms = [ + "caca", + "pipi", + "cabinets", + "water-closet", + "latrines", + "🚽", + "double véssé", + "chaise percée", + "WC", + "waters", + "toilettes", + "toilette", + "chiotte", + "chiottes", + "le trône", + "le trones", + "pièce mystère", + "backroom", + "retailleau" + ] +} + +export const SHOWER_SYMBOL = new MapSymbol() +{ + SHOWER_SYMBOL.markerUrl = new URL("../icons/douches.svg", import.meta.url) + SHOWER_SYMBOL.genericName = "Douche" +} + +export const SWIMMING_POOL_SYMBOL = new MapSymbol() +{ + SWIMMING_POOL_SYMBOL.markerUrl = new URL("../icons/piscine.svg", import.meta.url) + SWIMMING_POOL_SYMBOL.genericName = "Piscine" + SWIMMING_POOL_SYMBOL.backgroundColor = "#366d73" + SWIMMING_POOL_SYMBOL.borderColor = "#366d73" +} + +export const VERBOTEN_AREA_SYMBOL = new MapSymbol() +{ + VERBOTEN_AREA_SYMBOL.genericName = "Zone interdite" + VERBOTEN_AREA_SYMBOL.backgroundColor = "#992700" + VERBOTEN_AREA_SYMBOL.borderColor = "#992700" +} + +export const BUILDING_SYMBOL = new MapSymbol() +{ + BUILDING_SYMBOL.genericName = "Batiment" + BUILDING_SYMBOL.backgroundColor = "#5a5a5a" + BUILDING_SYMBOL.borderColor = "white" +} + +export const WIFI_SYMBOL = new MapSymbol() +{ + WIFI_SYMBOL.genericName = "Wifi" + WIFI_SYMBOL.markerUrl = new URL("../icons/wifi.svg", import.meta.url) +} \ No newline at end of file From 7d45e2f71710ce4f496e8724637aadf5e262e1b5 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Sun, 7 Jun 2026 12:22:41 +0200 Subject: [PATCH 3/6] Ajout d'un panneau vertical pour le resultat de la recerche --- css/style.css | 104 +++++++++- icons/arrow-left.svg | 19 ++ icons/arrow-right.svg | 19 ++ index.html | 20 +- js/components/bidi-panel.js | 264 ++++++++++++++++++++++++++ js/components/feature-short-header.js | 43 +++++ js/components/feature.js | 26 +++ js/index.js | 72 ++++++- 8 files changed, 549 insertions(+), 18 deletions(-) create mode 100644 icons/arrow-left.svg create mode 100644 icons/arrow-right.svg create mode 100644 js/components/bidi-panel.js create mode 100644 js/components/feature-short-header.js create mode 100644 js/components/feature.js diff --git a/css/style.css b/css/style.css index 7794b4f..c61fd99 100644 --- a/css/style.css +++ b/css/style.css @@ -5,12 +5,29 @@ body, html { body { pointer-events: none; + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + + min-height: 100vh; } body > * { pointer-events: all; } +body > hr { + border: none; + padding: 0; + margin: 0; + flex: 1; + min-height: 50vh; + flex-shrink: 0; + pointer-events: none; +} + /* HEADER and NAV */ #main-header { @@ -112,4 +129,89 @@ body > * { filter: drop-shadow(0 0 10px black); opacity: clamp(0, calc( 1 - ( var(--zoom-level) - 18 ) ), 1) ; pointer-events: none; -} \ No newline at end of file +} + +/* SAERCH FORM */ + +#search-section { + position: sticky; + top: 0; + left: 0; + z-index: 100i; +} + +/* PANEL */ + +#result-panel { + background: black; + border-top: 3px white solid; + + color: white; +} + +#result-panel.empty, +#result-panel:empty{ + display:none; +} + +#result-panel > * { + padding: 1em; + margin: 0; +} + +#result-panel::part(navigation-panel) { + background: black; + color: white; + box-shadow: 0 0 10px black; + border-top: solid 1px rgba(255, 255, 255, 0.5); +} + +#result-panel::part(dot), +#result-panel::part(dot-active) { + border-radius: 0; + width: 1ex; + height: 1ex; + margin-top: 0.5ex; +} + +#result-panel::part(dot-active) { + transform-origin: 0% 100%; + transform: scaleX(1) scaleY(1.5); +} + +camp-feature-short-header { + display: grid; + grid-template-rows: 1fr min-content; + grid-template-columns: 1fr; +} + +camp-feature-short-header h2 { + margin: 0; + padding: 0; + font-size: 1em; + font-weight: bold; +} + +camp-feature-short-header .feature-location { + margin: 0; + padding: 0; + font-size: 0.6em; + opacity: 0.75; +} + +#search-result { + list-style-type: none; +} + +#search-result > li:not(:first-child) { + margin-top: 1em; +} + +#search-result > li:not(:last-child) { + margin-bottom: 1em; +} + +#search-result > li > a { + text-decoration: none; + color: inherit; +} diff --git a/icons/arrow-left.svg b/icons/arrow-left.svg new file mode 100644 index 0000000..666b191 --- /dev/null +++ b/icons/arrow-left.svg @@ -0,0 +1,19 @@ + + + + diff --git a/icons/arrow-right.svg b/icons/arrow-right.svg new file mode 100644 index 0000000..51a6708 --- /dev/null +++ b/icons/arrow-right.svg @@ -0,0 +1,19 @@ + + + + diff --git a/index.html b/index.html index 32e8aab..7df51b7 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ +
@@ -14,26 +15,17 @@
- - - + +
+

-
    + - \ No newline at end of file + diff --git a/js/components/bidi-panel.js b/js/components/bidi-panel.js new file mode 100644 index 0000000..6a85da0 --- /dev/null +++ b/js/components/bidi-panel.js @@ -0,0 +1,264 @@ +const TEMPLATE = document.createElement("template"); +TEMPLATE.innerHTML = ` + + +
    + + +` + +export class BidiPanelElement extends HTMLElement { + + shadow + + mutationObserver + + #lastActive + #currentIndex + + get contentContainer(){ + return this.shadow.getElementById("content") + } + + get progressBar(){ + return this.shadow.getElementById("panel-progress-bar") + } + + get progressDotsContainer(){ + return this.shadow.getElementById("progress-dots") + } + + get activeChildrenIndex(){ + let thisGeometry = this.getBoundingClientRect() + let progress = this.contentContainer.scrollLeft / (this.contentContainer.scrollWidth - thisGeometry.width) + let focusedElementIndex = Math.floor(progress * this.children.length) + if(Number.isFinite(focusedElementIndex)){ + return focusedElementIndex + } else { + return null + } + } + + set activeChildrenIndex(newIndex){ + this.setActiveChildrenIndex(newIndex, {behavior: "auto"}) + } + + setActiveChildrenIndex(newIndex, options){ + let newPanel = this.children[newIndex] + let newPanelRect = newPanel.getBoundingClientRect() + let selfRect = this.getBoundingClientRect() + this.contentContainer.scrollTo({ + left: this.contentContainer.scrollLeft + ( newPanelRect.left - selfRect.left ), + behavior: options?.behavior || "auto" + }) + this.#currentIndex = newIndex + } + + get activeChildren(){ + return this.children[this.activeChildrenIndex] + } + + connectedCallback(){ + if(!this.shadow){ + this.shadow = this.attachShadow({ mode: "open" }) + this.shadow.append(TEMPLATE.content.cloneNode(true)) + } + this.contentContainer.addEventListener("scroll", this.handleContentScroll.bind(this)) + this.shadow.getElementById("nav-left-panel").addEventListener("click", () => this.previous()); + this.shadow.getElementById("nav-right-panel").addEventListener("click", () => this.next()); + + this.mutationObserver = (new MutationObserver(this.handleMutations.bind(this))) + this.mutationObserver.observe(this, {childList:true}) + + this.updateProgress() + } + + handleMutations(mutation){ + let newIndex = this.#currentIndex + this.updateProgress() + if(Number.isFinite(newIndex)){ + this.setActiveChildrenIndex(newIndex, {behavior: "instant"}) + } + } + + handleContentScroll(e){ + this.updateProgress() + this.#currentIndex = this.activeChildrenIndex + if(this.#currentIndex != this.#lastActive){ + this.dispatchEvent(new ActivePanelChangeEvent("activePanelChange", this.#currentIndex)) + this.#lastActive = this.#currentIndex + } + } + + updateProgress(){ + let focusedElementIndex = this.activeChildrenIndex; + + let progressBar = this.progressBar; + progressBar.value = focusedElementIndex; + progressBar.min = 0; + progressBar.max = this.children.length-1; + + this.classList.toggle("single-panel", this.children.length == 1) + this.classList.toggle("empty", this.children.length == 0) + + let dotsContainer = this.progressDotsContainer; + if(dotsContainer.children.length != parseInt(progressBar.max)+1){ + let dots = (new Array(this.children.length)) + .fill(0) + .map(() => { + let el = document.createElement("div") + el.classList.add("dot") + el.part = "dot" + return el + }); + dotsContainer.replaceChildren(...dots) + } + for(let inactiveDot of dotsContainer.querySelectorAll(".active")){ + inactiveDot.part = "dot" + inactiveDot.classList.remove("active") + } + + let activeDot = dotsContainer.children[parseInt(progressBar.value)] + if(activeDot){ + activeDot.part = "dot-active" + activeDot.classList.add("active") + } + } + + next(){ + let nextItem = this.activeChildrenIndex + 1; + if(nextItem < this.children.length){ + this.activeChildrenIndex = nextItem + } + } + + previous(){ + let nextItem = this.activeChildrenIndex - 1; + if(nextItem >= 0){ + this.activeChildrenIndex = nextItem + } + } +} + +export class ActivePanelChangeEvent extends Event { + constructor(name, activePanelIndex){ + super(name) + this.activePanelIndex = activePanelIndex + } +} + +customElements.define("camp-bidi-panel", BidiPanelElement); diff --git a/js/components/feature-short-header.js b/js/components/feature-short-header.js new file mode 100644 index 0000000..4dda14f --- /dev/null +++ b/js/components/feature-short-header.js @@ -0,0 +1,43 @@ +const TEMPLATE = document.createElement("template") +TEMPLATE.innerHTML = ` +

    + +` + +export class FeatureShortHeaderElement extends HTMLElement { + + #feature + + get feature(){ + return this.#feature + } + + set feature(value){ + this.#feature = value + } + + connectedCallback(){ + this.updateContent() + } + + updateContent(){ + if(!this.feature){ + this.replaceChildren() + } else { + this.replaceChildren(TEMPLATE.content.cloneNode(true)) + this.querySelector(".feature-name").textContent = + this.feature?.properties?.name || + this.feature.mapSymbol.genericName || + this.feature.id + + let featurePoint = this.feature.asPoint() + + this.querySelector(".feature-location").textContent = + this.feature?.properties?.["location-description"] || + `${featurePoint.geometry.coordinates[1]}, ${featurePoint.geometry.coordinates[0]}` + } + } + +} + +customElements.define("camp-feature-short-header", FeatureShortHeaderElement) diff --git a/js/components/feature.js b/js/components/feature.js new file mode 100644 index 0000000..a8fb046 --- /dev/null +++ b/js/components/feature.js @@ -0,0 +1,26 @@ +import "./feature-short-header.js" + +const TEMPLATE = document.createElement("template") +TEMPLATE.innerHTML = ` + +` + +export class FeatureElement extends HTMLElement { + + feature + + connectedCallback(){ + this.updateContent() + } + + updateContent(){ + this.replaceChildren(TEMPLATE.content.cloneNode(true)) + + let header = this.querySelector("camp-feature-short-header") + header.feature = this.feature + header.updateContent() + } + +} + +customElements.define("camp-feature", FeatureElement) diff --git a/js/index.js b/js/index.js index 2bff483..28141bd 100644 --- a/js/index.js +++ b/js/index.js @@ -1,5 +1,7 @@ import * as MAP from "./map.js" import { PlaceDatabase } from "./places.js"; +import {FeatureElement} from "./components/feature.js" +import "./components/feature-short-header.js" /** La carte */ @@ -47,18 +49,82 @@ search_form.addEventListener("submit", e => { let a = document.createElement("a") el.append(a) a.href = "#"+encodeURIComponent(result_item.ref) - a.textContent = result_item.feature.properties.name+" ("+result_item.ref+")" + a.addEventListener("click", e => { + e.preventDefault() + openSearchResultItem(result_item.feature) + }) + let header = document.createElement("camp-feature-short-header") + header.feature = result_item.feature + a.append(header) resultElements.push(el) } + if(!document.getElementById("search-result")){ + let el = document.createElement("ol") + el.id = "search-result" + document.getElementById("result-panel").replaceChildren(el) + } + if(resultElements.length > 0){ document.getElementById("search-result").replaceChildren(...resultElements) } else { document.getElementById("search-result").replaceChildren(document.createTextNode("Pas de resultat")) } + + document.getElementById("search-result").children[0]?.scrollIntoView() } else { - document.getElementById("search-result").replaceChildren([]) + document.getElementById("search-result")?.remove() } } -}) \ No newline at end of file +}) + +function openSearchResultItem(feature){ + let searchResultContainer = document.getElementById("search-result") + if(searchResultContainer){ + let featureIndex = -1 + let featureFound = false + let newChildren = [] + for(let el of searchResultContainer.children){ + let featureHeader = el.querySelector("camp-feature-short-header") + if(!featureHeader) + continue + let root = document.createElement("camp-feature") + root.feature = featureHeader.feature + newChildren.push(root) + if(!featureFound){ + featureIndex += 1 + if(feature == root.feature){ + featureFound = true + } + } + } + let panel = document.getElementById("result-panel") + panel.replaceChildren(...newChildren) + requestAnimationFrame(() => { + if(featureFound){ + panel.setActiveChildrenIndex(featureIndex, {behavior: "instant"}) + } else { + panel.activeChildrenIndex = 0 + } + }) + let newUrl = new URL(window.location) + newUrl.hash = feature.id + window.history.replaceState(newUrl.toString(), "") + } +} + +document.getElementById("result-panel").addEventListener("activePanelChange", e => { + let activeElement = e.target.children[e.activePanelIndex] + if(activeElement instanceof FeatureElement){ + let feature = activeElement.feature + if(feature){ + MAP.highlight(feature.id) + } else { + MAP.unhighlight_all() + } + console.log("active panel changed: "+e.activePanelIndex, feature) + } else { + MAP.unhighlight_all() + } +}) From af337ea0bf6e91c2ba53afef59029ceec952ce44 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Sun, 7 Jun 2026 15:41:57 +0200 Subject: [PATCH 4/6] Focus du resultat dans la liste et dans l'URL --- js/components/bidi-panel.js | 16 +++++++++++++--- js/index.js | 22 +++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/js/components/bidi-panel.js b/js/components/bidi-panel.js index 6a85da0..73e09e3 100644 --- a/js/components/bidi-panel.js +++ b/js/components/bidi-panel.js @@ -147,7 +147,11 @@ export class BidiPanelElement extends HTMLElement { let progress = this.contentContainer.scrollLeft / (this.contentContainer.scrollWidth - thisGeometry.width) let focusedElementIndex = Math.floor(progress * this.children.length) if(Number.isFinite(focusedElementIndex)){ - return focusedElementIndex + if(focusedElementIndex == this.children.length){ + return this.children.length - 1 + } else { + return focusedElementIndex + } } else { return null } @@ -193,14 +197,20 @@ export class BidiPanelElement extends HTMLElement { if(Number.isFinite(newIndex)){ this.setActiveChildrenIndex(newIndex, {behavior: "instant"}) } + this.requestDispatchChangeEvent() } handleContentScroll(e){ this.updateProgress() this.#currentIndex = this.activeChildrenIndex - if(this.#currentIndex != this.#lastActive){ + this.requestDispatchChangeEvent() + } + + requestDispatchChangeEvent(){ + let currentPanel = this.activeChildren + if(currentPanel != this.#lastActive){ this.dispatchEvent(new ActivePanelChangeEvent("activePanelChange", this.#currentIndex)) - this.#lastActive = this.#currentIndex + this.#lastActive = currentPanel } } diff --git a/js/index.js b/js/index.js index 28141bd..91fb24a 100644 --- a/js/index.js +++ b/js/index.js @@ -108,22 +108,26 @@ function openSearchResultItem(feature){ panel.activeChildrenIndex = 0 } }) - let newUrl = new URL(window.location) - newUrl.hash = feature.id - window.history.replaceState(newUrl.toString(), "") + updateActiveFeature(feature) } } +function updateActiveFeature(feature_or_featureid){ + let newUrl = new URL(window.location) + if(feature_or_featureid){ + newUrl.hash = encodeURIComponent(feature_or_featureid.id || feature_or_featureid) + } else { + delete newUrl.hash; + } + window.history.replaceState(null, "", newUrl.toString()) + window.dispatchEvent(new Event("hashchange")) +} + document.getElementById("result-panel").addEventListener("activePanelChange", e => { let activeElement = e.target.children[e.activePanelIndex] if(activeElement instanceof FeatureElement){ let feature = activeElement.feature - if(feature){ - MAP.highlight(feature.id) - } else { - MAP.unhighlight_all() - } - console.log("active panel changed: "+e.activePanelIndex, feature) + updateActiveFeature(feature) } else { MAP.unhighlight_all() } From 48aad70993d4896aa0cf60ec1dc27e2a47ff57b6 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Sun, 7 Jun 2026 17:45:21 +0200 Subject: [PATCH 5/6] Ajout des legendes --- css/style.css | 16 +++++- js/components/feature-legend.js | 72 +++++++++++++++++++++++++++ js/components/feature-short-header.js | 11 ++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 js/components/feature-legend.js diff --git a/css/style.css b/css/style.css index c61fd99..f6fd981 100644 --- a/css/style.css +++ b/css/style.css @@ -182,7 +182,15 @@ body > hr { camp-feature-short-header { display: grid; grid-template-rows: 1fr min-content; - grid-template-columns: 1fr; + grid-template-columns: 3em 1fr; + gap: 0.5ex 0.5em; + vertical-align: center; +} + +camp-feature-short-header .feature-legend { + grid-row: 1 / 3; + height: 3em; + align-self: flex-start; } camp-feature-short-header h2 { @@ -215,3 +223,9 @@ camp-feature-short-header .feature-location { text-decoration: none; color: inherit; } + +/* FEATURE */ + +camp-feature { + min-height: 25vh; +} diff --git a/js/components/feature-legend.js b/js/components/feature-legend.js new file mode 100644 index 0000000..03ddb78 --- /dev/null +++ b/js/components/feature-legend.js @@ -0,0 +1,72 @@ +const TEMPLATE = document.createElement("template") +TEMPLATE.innerHTML = ` + +
    + +
    +` + +export class FeatureLegendElement extends HTMLElement { + + feature + + connectedCallback(){ + if(!this.shadow){ + this.shadow = this.attachShadow({mode: "open"}) + this.shadow.append(TEMPLATE.content.cloneNode(true)) + } + this.updateContent() + } + + updateContent(){ + let container = this.shadow.getElementById("legend-container") + let marker = this.shadow.getElementById("marker-icon") + container.hidden = !this.feature + if(this.feature){ + let symbol = this.feature.mapSymbol + container.style.backgroundColor = symbol.backgroundColor || "transparent" + container.style.backgroundImage = symbol.backgroundUrl ? `url(${symbol.backgroundUrl})` : "none" + container.style.borderColor = symbol.borderColor || "transparent" + if(symbol.markerUrl){ + marker.src = symbol.markerUrl + } else { + marker.removeAttribute("src") + } + } + } + +} + +customElements.define("camp-feature-legend", FeatureLegendElement) diff --git a/js/components/feature-short-header.js b/js/components/feature-short-header.js index 4dda14f..e40adec 100644 --- a/js/components/feature-short-header.js +++ b/js/components/feature-short-header.js @@ -1,5 +1,8 @@ +import "./feature-legend.js" + const TEMPLATE = document.createElement("template") TEMPLATE.innerHTML = ` +

    ` @@ -14,6 +17,9 @@ export class FeatureShortHeaderElement extends HTMLElement { set feature(value){ this.#feature = value + let legend = this.querySelector(".feature-legend") + if(legend) + legend.feature = value } connectedCallback(){ @@ -24,7 +30,12 @@ export class FeatureShortHeaderElement extends HTMLElement { if(!this.feature){ this.replaceChildren() } else { + this.replaceChildren(TEMPLATE.content.cloneNode(true)) + + this.querySelector(".feature-legend").feature = this.feature + this.querySelector(".feature-legend").updateContent() + this.querySelector(".feature-name").textContent = this.feature?.properties?.name || this.feature.mapSymbol.genericName || From 255c47183d07d6d55b19342a8c830c264f98aaf1 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Sun, 7 Jun 2026 22:29:27 +0200 Subject: [PATCH 6/6] Ajout des borduresw --- assets/button-stepped-border-image.svg | 66 +++ assets/neon-border-image.svg | 69 ++++ css/style.css | 53 ++- icons/search.svg | 541 +++++++++++++++++++++++++ index.html | 14 +- js/index.js | 2 +- 6 files changed, 732 insertions(+), 13 deletions(-) create mode 100644 assets/button-stepped-border-image.svg create mode 100644 assets/neon-border-image.svg create mode 100644 icons/search.svg diff --git a/assets/button-stepped-border-image.svg b/assets/button-stepped-border-image.svg new file mode 100644 index 0000000..229a1aa --- /dev/null +++ b/assets/button-stepped-border-image.svg @@ -0,0 +1,66 @@ + + + + diff --git a/assets/neon-border-image.svg b/assets/neon-border-image.svg new file mode 100644 index 0000000..b78b240 --- /dev/null +++ b/assets/neon-border-image.svg @@ -0,0 +1,69 @@ + + + + diff --git a/css/style.css b/css/style.css index f6fd981..7e65655 100644 --- a/css/style.css +++ b/css/style.css @@ -134,17 +134,60 @@ body > hr { /* SAERCH FORM */ #search-section { - position: sticky; - top: 0; - left: 0; - z-index: 100i; + border: solid 10px black; + border-image: url("../assets/button-stepped-border-image.svg") 16 15 fill; + z-index: 100; + margin-bottom: 5px; + margin-left: 5px; + width: fit-content; + max-width: 100%; + background: black; + background-clip: content-box; + color: white; + + display: grid; + grid-template-columns: min-content 1fr; + grid-template-rows: 1fr; +} + +#search-section input { + background: black; + font-size: 1em; + color: inherit; + font-family: monospace; + border: none; + padding: 1ex; + + grid-column: 2; + grid-row: 1; +} + +#search-section button { + background: transparent; + border: none; + padding: 1ex; + grid-column: 1; + grid-row: 1; + cursor: pointer; +} + +#search-section label { + grid-column: 2; + grid-row: 1; + padding: 1ex; + align-self: flex-end; +} + +#search-section button img { + height: 1.5em; } /* PANEL */ #result-panel { background: black; - border-top: 3px white solid; + border-image: url("../assets/neon-border-image.svg") 12; + border-top: 5.5px white solid; color: white; } diff --git a/icons/search.svg b/icons/search.svg new file mode 100644 index 0000000..535d2ef --- /dev/null +++ b/icons/search.svg @@ -0,0 +1,541 @@ + + + +Piscine++++++Piscine de l'AntenneAu centre de la pelouse d'entree sur le site, a cote des jeux pour enfantGrand atelier de nage libre, tous cyborg accepteEVENEMENTS A VENIRNage libre3 Juil17:00-19:00 diff --git a/index.html b/index.html index 7df51b7..7163235 100644 --- a/index.html +++ b/index.html @@ -18,13 +18,13 @@
    -
    -
    -
    - - -
    -
    +
    +
    + + +
    diff --git a/js/index.js b/js/index.js index 91fb24a..e8fcae3 100644 --- a/js/index.js +++ b/js/index.js @@ -21,7 +21,7 @@ window.interhackPlaces = places; await MAP.init_places(places) // GESTION de la recherche -const search_form = document.getElementById("search-area") +const search_form = document.getElementById("search-section") search_form.elements["query"].addEventListener("change", () => search_form.requestSubmit()) search_form.elements["query"].addEventListener("input", () => search_form.requestSubmit())