Rough data setup

This commit is contained in:
Alexis
2026-03-24 21:50:04 +01:00
parent 16b28f5e12
commit 5a52b08107
5 changed files with 112 additions and 5 deletions

View File

@@ -15,6 +15,7 @@
"format": "oxfmt src/"
},
"dependencies": {
"@pinia/colada": "^1.0.0",
"@tailwindcss/vite": "^4.2.2",
"@vueuse/core": "^14.2.1",
"pinia": "^3.0.4",

19
pnpm-lock.yaml generated
View File

@@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@pinia/colada':
specifier: ^1.0.0
version: 1.0.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))
'@tailwindcss/vite':
specifier: ^4.2.2
version: 4.2.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
@@ -25,7 +28,7 @@ importers:
version: 3.5.30(typescript@5.9.3)
vue-router:
specifier: ^5.0.3
version: 5.0.4(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))
version: 5.0.4(@pinia/colada@1.0.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)))(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))
devDependencies:
'@tsconfig/node24':
specifier: ^24.0.4
@@ -695,6 +698,12 @@ packages:
cpu: [x64]
os: [win32]
'@pinia/colada@1.0.0':
resolution: {integrity: sha512-YKSybA6wusFK4CAUPzItoSgPCfScVnnnO2MSlmaaisE/L7luE77GxFyhTzipM8IbvbXh4zkCy97OE7w9WX34wA==}
peerDependencies:
pinia: ^2.2.6 || ^3.0.0
vue: ^3.5.17
'@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
@@ -2517,6 +2526,11 @@ snapshots:
'@oxlint/binding-win32-x64-msvc@1.51.0':
optional: true
'@pinia/colada@1.0.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))':
dependencies:
pinia: 3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3))
vue: 3.5.30(typescript@5.9.3)
'@polka/url@1.0.0-next.29': {}
'@rolldown/pluginutils@1.0.0-rc.2': {}
@@ -3787,7 +3801,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
vue-router@5.0.4(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)):
vue-router@5.0.4(@pinia/colada@1.0.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)))(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)):
dependencies:
'@babel/generator': 7.29.1
'@vue-macros/common': 3.1.2(vue@3.5.30(typescript@5.9.3))
@@ -3808,6 +3822,7 @@ snapshots:
vue: 3.5.30(typescript@5.9.3)
yaml: 2.8.3
optionalDependencies:
'@pinia/colada': 1.0.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))
'@vue/compiler-sfc': 3.5.30
pinia: 3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3))

78
src/components/Map.vue Normal file
View File

@@ -0,0 +1,78 @@
<script lang="ts" setup>
import { ref } from 'vue'
const BASE_URL = 'https://data.rennesmetropole.fr/api/explore/v2.1/catalog/datasets/parkings_velos_sur_rennes_metropole/records'
const LIMIT = 100
interface GeoPoint {
lon: number
lat: number
}
interface GeoShape {
type: 'Feature'
geometry: {
coordinates: [number, number]
type: 'Point'
}
properties: Record<string, unknown>
}
interface BikeParking {
geo_point_2d: GeoPoint
geo_shape: GeoShape
gml_id: string
id_parc_velo: number
nom: string | null
code_insee: number
nom_commune: string
nom_voie: string
id_voie: number
type: string
gestionnaire: string
localisation: string
condition_acces: string
annee_mes: number
nb_support_std: number | null
nb_support_cargo: number | null
nb_total_place: number
date_maj: string
commentaire: string | null
}
interface ApiResponse {
total_count: number
results: BikeParking[]
}
const res = ref<BikeParking[]>([])
const firstPage = await fetch(`${BASE_URL}?limit=${LIMIT}`).then(r => r.json()) as ApiResponse
const { total_count } = firstPage
const remainingPages = await Promise.all(
Array.from(
{ length: Math.ceil((total_count - LIMIT) / LIMIT) },
(_, i) => fetch(`${BASE_URL}?limit=${LIMIT}&offset=${(i + 1) * LIMIT}`).then(r => r.json()) as Promise<ApiResponse>
)
)
res.value = [
...(firstPage.results ?? []),
...remainingPages.flatMap(page => page.results ?? [])
]
</script>
<template>
<header class="sr-only">
<h1>
Carte interactive des parkings vélo de Rennes Métropole
</h1>
</header>
<main class="h-screen w-screen grid place-items-center">
<pre>
{{ res }}
</pre>
</main>
</template>

View File

@@ -1,5 +1,6 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { PiniaColada } from '@pinia/colada'
import App from './App.vue'
import router from './router'
@@ -7,6 +8,8 @@ import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(PiniaColada)
app.use(router)
app.mount('#app')

View File

@@ -1,5 +1,15 @@
<script setup lang="ts">
import Map from '@/components/Map.vue';
</script>
<template>
<main>
Home
</main>
<header class="sr-only">
<h1>
Carte interactive des parkings vélo de Rennes Métropole
</h1>
</header>
<Suspense>
<Map />
</Suspense>
</template>