diff --git a/assets/utils.js b/assets/utils.js
index 8b692b7..7358a94 100644
--- a/assets/utils.js
+++ b/assets/utils.js
@@ -1,3 +1,4 @@
+
function colorHeadingTable() {
const headers = document.querySelectorAll('th');
@@ -20,7 +21,7 @@ function check_validity(e) {
'input[name="commerce_tag_value__contact:email"]',
'input[name="commerce_tag_value__contact:phone"]',
'input[name="commerce_tag_value__contact:website"]',
- 'input[name="commerce_tag_value__contact:mastodon"]',
+ 'commerce_tag_value__contact:mastodon',
'input[name="commerce_tag_value__address"]',
'input[name="custom_opening_hours"]',
'input[name="commerce_tag_value__contact:street"]',
diff --git a/labourage.sh b/labourage.sh
index 59dca32..cc51777 100644
--- a/labourage.sh
+++ b/labourage.sh
@@ -12,18 +12,6 @@ codes_insee=(
"33063" # Bordeaux
"59350" # Lille
"35238" # Rennes
- "75101" # Paris 1er
- "75102" # Paris 2e
- "75103" # Paris 3e
- "75104" # Paris 4e
- "75105" # Paris 5e
- "75106" # Paris 6e
- "75107" # Paris 7e
- "75108" # Paris 8e
- "75109" # Paris 9e
- "75110" # Paris 10e
- "75111" # Paris 11e
- "75112" # Paris 12e
"75113" # Paris 13e
"75114" # Paris 14e
"75115" # Paris 15e
diff --git a/migrations/Version20250617141249.php b/migrations/Version20250617141249.php
deleted file mode 100644
index 006f42b..0000000
--- a/migrations/Version20250617141249.php
+++ /dev/null
@@ -1,35 +0,0 @@
-addSql(<<<'SQL'
- ALTER TABLE place ADD habitants INT DEFAULT NULL
- SQL);
- }
-
- public function down(Schema $schema): void
- {
- // this down() migration is auto-generated, please modify it to your needs
- $this->addSql(<<<'SQL'
- ALTER TABLE place DROP habitants
- SQL);
- }
-}
diff --git a/migrations/Version20250617141824.php b/migrations/Version20250617141824.php
deleted file mode 100644
index c6d01f3..0000000
--- a/migrations/Version20250617141824.php
+++ /dev/null
@@ -1,35 +0,0 @@
-addSql(<<<'SQL'
- ALTER TABLE stats ADD population INT DEFAULT NULL
- SQL);
- }
-
- public function down(Schema $schema): void
- {
- // this down() migration is auto-generated, please modify it to your needs
- $this->addSql(<<<'SQL'
- ALTER TABLE stats DROP population
- SQL);
- }
-}
diff --git a/public/assets/img/josm.png b/public/assets/img/josm.png
deleted file mode 100644
index 1764904..0000000
Binary files a/public/assets/img/josm.png and /dev/null differ
diff --git a/public/assets/img/logo-osm.png b/public/assets/img/logo-osm.png
deleted file mode 100644
index 4388167..0000000
Binary files a/public/assets/img/logo-osm.png and /dev/null differ
diff --git a/public/assets/img/osm-id.png b/public/assets/img/osm-id.png
deleted file mode 100644
index 2ea1914..0000000
Binary files a/public/assets/img/osm-id.png and /dev/null differ
diff --git a/public/js/utils.js b/public/js/utils.js
deleted file mode 100644
index bc42570..0000000
--- a/public/js/utils.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// Fonction pour gérer la recherche de villes
-/**
- * Configure la recherche de ville avec autocomplétion
- * @param {string} inputId - ID de l'input de recherche
- * @param {string} suggestionListId - ID de la liste des suggestions
- * @param {Function} onSelect - Callback appelé lors de la sélection d'une ville
- */
-export function setupCitySearch(inputId, suggestionListId, onSelect) {
- const searchInput = document.getElementById(inputId);
- const suggestionList = document.getElementById(suggestionListId);
-
- if (!searchInput || !suggestionList) return;
-
- let timeoutId = null;
-
- searchInput.addEventListener('input', function () {
- clearTimeout(timeoutId);
- const query = this.value.trim();
-
- if (query.length < 2) {
- clearSuggestions();
- return;
- }
-
- timeoutId = setTimeout(() => performSearch(query), 300);
- });
-
- function performSearch(query) {
- fetch(`https://geo.api.gouv.fr/communes?nom=${encodeURIComponent(query)}&fields=nom,code,codesPostaux&limit=5`)
- .then(response => response.json())
- .then(data => {
- const citySuggestions = data.map(city => ({
- name: city.nom,
- postcode: city.codesPostaux[0],
- insee: city.code
- }));
- displaySuggestions(citySuggestions);
- })
- .catch(error => {
- console.error('Erreur lors de la recherche:', error);
- clearSuggestions();
- });
- }
-
- function displaySuggestions(suggestions) {
- clearSuggestions();
- suggestions.forEach(suggestion => {
- const li = document.createElement('li');
- li.className = 'list-group-item';
- li.textContent = `${suggestion.name} (${suggestion.postcode})`;
- li.addEventListener('click', () => {
- searchInput.value = suggestion.name;
- clearSuggestions();
- if (onSelect) onSelect(suggestion);
- });
- suggestionList.appendChild(li);
- });
- }
-
- function clearSuggestions() {
- suggestionList.innerHTML = '';
- }
-
- // Fermer les suggestions en cliquant en dehors
- document.addEventListener('click', function (e) {
- if (!searchInput.contains(e.target) && !suggestionList.contains(e.target)) {
- clearSuggestions();
- }
- });
-}
-
-// Fonction pour formater l'URL de labourage
-/**
- * Génère l'URL de labourage pour un code postal donné
- * @param {string} zipCode - Le code postal
- * @returns {string} L'URL de labourage
- */
-export function getLabourerUrl(zipCode) {
- return `/admin/labourer/${zipCode}`;
-}
-
-// Fonction pour gérer la soumission du formulaire d'ajout de ville
-export function handleAddCityFormSubmit(event) {
- event.preventDefault();
- const form = event.target;
- const submitButton = form.querySelector('button[type="submit"]');
- const zipCodeInput = form.querySelector('input[name="zip_code"]');
- if (!zipCodeInput.value) {
- return;
- }
- // Afficher le spinner
- submitButton.disabled = true;
- const originalContent = submitButton.innerHTML;
- submitButton.innerHTML = ' Labourer...';
- // Rediriger
- window.location.href = getLabourerUrl(zipCodeInput.value);
-}
-
-/**
- * Colore les cellules d'un tableau en fonction des pourcentages
- * @param {string} selector - Le sélecteur CSS pour cibler les cellules à colorer
- * @param {string} color - La couleur de base en format RGB (ex: '154, 205, 50')
- */
-export function colorizePercentageCells(selector, color = '154, 205, 50') {
- document.querySelectorAll(selector).forEach(cell => {
- const percentage = parseInt(cell.textContent);
- if (!isNaN(percentage)) {
- const alpha = percentage / 100;
- cell.style.backgroundColor = `rgba(${color}, ${alpha})`;
- }
- });
-}
-
-/**
- * Colore les cellules d'un tableau avec un gradient relatif à la valeur maximale
- * @param {string} selector - Le sélecteur CSS pour cibler les cellules à colorer
- * @param {string} color - La couleur de base en format RGB (ex: '154, 205, 50')
- */
-export function colorizePercentageCellsRelative(selector, color = '154, 205, 50') {
- // Récupérer toutes les cellules
- const cells = document.querySelectorAll(selector);
-
- // Trouver la valeur maximale
- let maxValue = 0;
- cells.forEach(cell => {
- const value = parseInt(cell.textContent);
- if (!isNaN(value) && value > maxValue) {
- maxValue = value;
- }
- });
-
- // Appliquer le gradient relatif à la valeur max
- cells.forEach(cell => {
- const value = parseInt(cell.textContent);
- if (!isNaN(value)) {
- const alpha = value / maxValue; // Ratio relatif au maximum
- cell.style.backgroundColor = `rgba(${color}, ${alpha})`;
- }
- });
-}
-
-/**
- * Ajuste dynamiquement la taille du texte des éléments list-group-item selon leur nombre
- * @param {string} selector - Le sélecteur CSS des éléments à ajuster
- * @param {number} [minFont=0.8] - Taille de police minimale en rem
- * @param {number} [maxFont=1.2] - Taille de police maximale en rem
- */
-export function adjustListGroupFontSize(selector, minFont = 0.8, maxFont = 1.2) {
- const items = document.querySelectorAll(selector);
- const count = items.length;
- let fontSize = maxFont;
- if (count > 0) {
- // Plus il y a d'items, plus la taille diminue, mais jamais en dessous de minFont
- fontSize = Math.max(minFont, maxFont - (count - 5) * 0.05);
- }
- items.forEach(item => {
- item.style.fontSize = fontSize + 'rem';
- });
-}
-
-function check_validity() {
- if (!document.getElementById('editLand')) {
- return;
- }
- // ... suite du code ...
-}
\ No newline at end of file
diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php
index 0b3b30f..6c74ab3 100644
--- a/src/Controller/AdminController.php
+++ b/src/Controller/AdminController.php
@@ -131,8 +131,10 @@ final class AdminController extends AbstractController
// Récupérer ou créer les stats pour cette zone
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zip_code]);
+
$city = $this->motocultrice->get_city_osm_from_zip_code($zip_code);
if (!$stats) {
+
$stats = new Stats();
$stats->setZone($zip_code)
->setPlacesCount(0)
@@ -142,26 +144,10 @@ final class AdminController extends AbstractController
->setAvecAccessibilite(0)
->setAvecNote(0)
->setCompletionPercent(0);
- $this->entityManager->persist($stats);
- $this->entityManager->flush();
- }
- $stats->setName($city);
-
- // Récupérer la population via l'API
- $population = null;
- try {
- $apiUrl = 'https://geo.api.gouv.fr/communes/' . $zip_code . '?fields=population';
- $response = file_get_contents($apiUrl);
- if ($response !== false) {
- $data = json_decode($response, true);
- if (isset($data['population'])) {
- $population = (int)$data['population'];
- $stats->setPopulation($population);
+ $this->entityManager->persist($stats);
+ $this->entityManager->flush();
}
- }
- } catch (\Exception $e) {
- // Ne rien faire si l'API échoue
- }
+ $stats->setName($city);
// Récupérer toutes les données
$places = $this->motocultrice->labourer($zip_code);
diff --git a/src/Controller/PublicController.php b/src/Controller/PublicController.php
index 593c560..7dff42e 100644
--- a/src/Controller/PublicController.php
+++ b/src/Controller/PublicController.php
@@ -102,7 +102,7 @@ class PublicController extends AbstractController
$message = (new Email())
->from('contact@osm-commerce.fr')
->to($destinataire)
- ->subject('Votre lien de modification OpenStreetMap')
+ ->subject('Votre lien de modification Ope nStreetMap')
->text('Bonjour, nous sommes des bénévoles d\'OpenStreetMap France et nous vous proposons de modifier les informations de votre commerce. Voici votre lien unique de modification: ' . $this->generateUrl('app_public_edit', [
'zipcode' => $zipCode,
'name' => $place_name,
@@ -117,11 +117,10 @@ class PublicController extends AbstractController
#[Route('/', name: 'app_public_index')]
public function index(): Response
{
- $stats = $this->entityManager->getRepository(Stats::class)->findAll();
return $this->render('public/home.html.twig', [
'controller_name' => 'PublicController',
- 'stats' => $stats
+
]);
}
@@ -191,6 +190,7 @@ class PublicController extends AbstractController
#[Route('/modify/{osm_object_id}/{version}/{changesetID}', name: 'app_public_submit')]
public function submit($osm_object_id, $version, $changesetID): Response
{
+
$place = $this->entityManager->getRepository(Place::class)->findOneBy(['osmId' => $osm_object_id]);
if (!$place) {
$this->addFlash('warning', 'Ce commerce n\'existe pas.');
@@ -212,9 +212,11 @@ class PublicController extends AbstractController
$request_post = $request->request->all();
+
$request_post = $this->motocultrice->map_post_values($request_post);
foreach ($request_post as $key => $value) {
+
if (strpos($key, 'commerce_tag_value__') === 0) {
$tagKey = str_replace('commerce_tag_value__', '', $key);
if (!empty($value)) {
@@ -234,6 +236,7 @@ class PublicController extends AbstractController
// Récupérer le token OSM depuis les variables d'environnement
$osm_api_token = $_ENV['APP_OSM_BEARER'];
+
$exception = false;
$exception_message = "";
try {
@@ -290,6 +293,7 @@ class PublicController extends AbstractController
// Debug du XML généré
$xmlString = $xml->asXML();
+ // echo('xml :
'.$xmlString);
$response = $client->put("https://api.openstreetmap.org/api/0.6/{$osm_kind}/" . $osm_object_id, [
'body' => $xmlString,
@@ -323,13 +327,15 @@ class PublicController extends AbstractController
}
// après envoi on récupère les données
- $commerce_overpass = $this->motocultrice->get_osm_object_data($osm_kind, $osm_object_id);
+ $commerce = $this->motocultrice->get_osm_object_data($osm_kind, $osm_object_id);
- $place->update_place_from_overpass_data($commerce_overpass);
+
+ $place->update_place_from_overpass_data($commerce);
$this->entityManager->persist($place);
$this->entityManager->flush();
$this->entityManager->clear();
+
$stats = $place->getStats();
if(!$stats) {
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zip_code' => $place->getZipCode()]);
@@ -339,20 +345,19 @@ class PublicController extends AbstractController
$stats->setZipCode($place->getZipCode());
}
- $stats->addPlace($place);
- $place->setStats($stats);
- $place->setModifiedDate(new \DateTime());
+ $stats->addPlace($place);
+ $place->setStats($stats);
+ $place->setModifiedDate(new \DateTime());
- $stats->computeCompletionPercent();
- $this->entityManager->persist($stats);
- $this->entityManager->persist($place);
- $this->entityManager->flush();
- $this->entityManager->clear();
+ $stats->computeCompletionPercent();
+ $this->entityManager->persist($stats);
+ $this->entityManager->persist($place);
+ $this->entityManager->flush();
+ $this->entityManager->clear();
return $this->render('public/view.html.twig', [
'controller_name' => 'PublicController',
- 'commerce' => $commerce_overpass,
- 'commerce_overpass' => $commerce_overpass,
+ 'commerce' => $commerce,
'place' => $place,
'status' => $status,
'exception' => $exception,
diff --git a/src/Entity/Place.php b/src/Entity/Place.php
index a3d3328..1ceb91b 100644
--- a/src/Entity/Place.php
+++ b/src/Entity/Place.php
@@ -100,9 +100,6 @@ class Place
#[ORM\Column(length: 255, nullable: true)]
private ?string $siret = null;
- #[ORM\Column(nullable: true)]
- private ?int $habitants = null;
-
public function getMainTag(): ?string
{
return $this->main_tag;
@@ -582,16 +579,4 @@ class Place
return $this;
}
-
- public function getHabitants(): ?int
- {
- return $this->habitants;
- }
-
- public function setHabitants(?int $habitants): static
- {
- $this->habitants = $habitants;
-
- return $this;
- }
}
diff --git a/src/Entity/Stats.php b/src/Entity/Stats.php
index 6db0de4..872fda9 100644
--- a/src/Entity/Stats.php
+++ b/src/Entity/Stats.php
@@ -17,7 +17,7 @@ class Stats
private ?int $id = null;
#[ORM\Column(length: 255)]
- private ?string $zone = null; // code insee de la zone
+ private ?string $zone = null;
#[ORM\Column(type: Types::SMALLINT)]
private ?int $completion_percent = null;
@@ -55,10 +55,6 @@ class Stats
#[ORM\Column(length: 255, nullable: true)]
private ?string $name = null;
- // nombre d'habitants dans la zone
- #[ORM\Column(type: Types::INTEGER, nullable: true)]
- private ?int $population = null;
-
// calcule le pourcentage de complétion de la zone
public function computeCompletionPercent(): ?int
{
@@ -259,17 +255,6 @@ class Stats
return $this;
}
-
- public function getPopulation(): ?int
- {
- return $this->population;
- }
-
- public function setPopulation(?int $population): static
- {
- $this->population = $population;
- return $this;
- }
}
diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig
index a4cf711..933415a 100644
--- a/templates/admin/stats.html.twig
+++ b/templates/admin/stats.html.twig
@@ -16,9 +16,6 @@
height: 300px;
margin: 20px 0;
}
- .completion-info {
- margin-bottom: 2rem;
- }
{% endblock %}
@@ -37,27 +34,6 @@
- {% if stats.population %}
-
- {{query_places|raw}} -- - Exécuter dans Overpass Turbo - -
+ {{query_places|raw}} ++
+ | {{ commerce.getCompletionPercentage() }} |
diff --git a/templates/public/dashboard.html.twig b/templates/public/dashboard.html.twig
index b1a21ce..a317a01 100644
--- a/templates/public/dashboard.html.twig
+++ b/templates/public/dashboard.html.twig
@@ -14,184 +14,216 @@
width: 100%;
margin-bottom: 1rem;
}
- .suggestion-list {
- position: absolute;
- background: white;
- border: 1px solid #ddd;
- border-radius: 4px;
- max-height: 200px;
- overflow-y: auto;
- width: 100%;
- z-index: 1000;
- display: none;
- }
- .suggestion-item {
- padding: 8px 12px;
- cursor: pointer;
- border-bottom: 1px solid #eee;
- }
- .suggestion-item:hover {
- background-color: #f5f5f5;
- }
- .suggestion-name {
- font-weight: bold;
- }
- .suggestion-details {
- font-size: 0.9em;
- color: #666;
- }
- .suggestion-type {
- margin-right: 8px;
- }
- .search-container {
- position: relative;
- margin-bottom: 1rem;
- }
{% endblock %}
{% block javascripts %}
{{ parent() }}
-
-
+
{% endblock %}
{% block body %}
-
+
-
- Tableau de bord+Dashboard
-
- Statistiques par ville-
-
-
Statistiques : {{ stats|length }} codes postaux+ + -
-
-
-
+
+
+
+
+
-
+ Chargement...
+ Labourer une ville-- - Rechercher une ville pour labourer ses commerces - - +
{{ places_count }} Lieux+ +
+
+
+ + {{ dump(commerce_overpass) }} +
@@ -15,7 +19,7 @@
{% if commerce_overpass is not empty %}
+
@@ -123,31 +130,23 @@
{{ 'display.by'|trans }}
{{ commerce_overpass['@attributes'].user }}
+
+
- {% if commerce.stats %}
-
- zone {{commerce.stats.zone}}
-
- {% endif %}
-
- Dashboard
+
+ Dashboard
diff --git a/templates/public/edit/tags.html.twig b/templates/public/edit/tags.html.twig
index 35500ac..ee403ef 100644
--- a/templates/public/edit/tags.html.twig
+++ b/templates/public/edit/tags.html.twig
@@ -1,45 +1,43 @@
{% block tags %}
|