mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-06-20 01:44:42 +02:00
search by insee code
This commit is contained in:
parent
8081889f1e
commit
8d83186a68
7 changed files with 130 additions and 78 deletions
|
@ -633,5 +633,82 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
table.classList.add('js-sort-table');
|
table.classList.add('js-sort-table');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function searchInseeCode(query) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Afficher l'indicateur de chargement
|
||||||
|
document.querySelector('#loading_search_insee').classList.remove('d-none');
|
||||||
|
const response = await fetch(`https://geo.api.gouv.fr/communes?nom=${query}&fields=nom,code,codesPostaux&limit=10`);
|
||||||
|
const data = await response.json();
|
||||||
|
return data.map(commune => ({
|
||||||
|
label: `${commune.nom} (code insee ${commune.code})`,
|
||||||
|
insee: commune.code,
|
||||||
|
postcodes: commune.codesPostaux
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la recherche du code INSEE:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifier la fonction de recherche existante
|
||||||
|
const searchInput = document.getElementById('app_admin_labourer');
|
||||||
|
const suggestionList = document.getElementById('suggestionList');
|
||||||
|
|
||||||
|
if (searchInput && suggestionList) {
|
||||||
|
let timeoutId;
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', () => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
const query = searchInput.value.trim();
|
||||||
|
|
||||||
|
if (query.length < 2) {
|
||||||
|
suggestionList.innerHTML = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutId = setTimeout(async () => {
|
||||||
|
const suggestions = await searchInseeCode(query);
|
||||||
|
suggestionList.innerHTML = '';
|
||||||
|
|
||||||
|
if (suggestions.length === 0) {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.style.cssText = `
|
||||||
|
padding: 8px 12px;
|
||||||
|
color: #666;
|
||||||
|
font-style: italic;
|
||||||
|
`;
|
||||||
|
li.textContent = 'Aucun résultat trouvé';
|
||||||
|
suggestionList.appendChild(li);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestions.forEach(suggestion => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.style.cssText = `
|
||||||
|
padding: 8px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
`;
|
||||||
|
li.textContent = suggestion.label;
|
||||||
|
|
||||||
|
li.addEventListener('mouseenter', () => {
|
||||||
|
li.style.backgroundColor = '#f0f0f0';
|
||||||
|
});
|
||||||
|
|
||||||
|
li.addEventListener('mouseleave', () => {
|
||||||
|
li.style.backgroundColor = 'white';
|
||||||
|
});
|
||||||
|
|
||||||
|
li.addEventListener('click', () => {
|
||||||
|
searchInput.value = suggestion.insee;
|
||||||
|
suggestionList.innerHTML = '';
|
||||||
|
labourer();
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionList.appendChild(li);
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
|
|
@ -169,7 +169,7 @@ class PublicController extends AbstractController
|
||||||
#[Route('/dashboard', name: 'app_public_dashboard')]
|
#[Route('/dashboard', name: 'app_public_dashboard')]
|
||||||
public function dashboard(): Response
|
public function dashboard(): Response
|
||||||
{
|
{
|
||||||
// get stats
|
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findAll();
|
$stats = $this->entityManager->getRepository(Stats::class)->findAll();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ class Motocultrice
|
||||||
];
|
];
|
||||||
|
|
||||||
// quand un commerce a fermé, on peut supprimer ces tags
|
// quand un commerce a fermé, on peut supprimer ces tags
|
||||||
public $obsolete_tags = ["phone", "website", "email", "description", "brand", "opening_hours",
|
public $obsolete_tags = [
|
||||||
|
"phone", "website", "email", "description", "brand", "opening_hours",
|
||||||
"check_date:opening_hours", "internet_access",
|
"check_date:opening_hours", "internet_access",
|
||||||
"indoor_seating", "takeaway", "female", "male", "unisex",
|
"indoor_seating", "takeaway", "female", "male", "unisex",
|
||||||
"ref:FR:NAF", "ref:FR:FINESS", "ref:FR:SIRET", "ref:FR:SIREN", "ref:vatin",
|
"ref:FR:NAF", "ref:FR:FINESS", "ref:FR:SIRET", "ref:FR:SIREN", "ref:vatin",
|
||||||
|
@ -52,10 +53,12 @@ class Motocultrice
|
||||||
"mobile", "sport", "produce", "lottery", "supermarket", "information",
|
"mobile", "sport", "produce", "lottery", "supermarket", "information",
|
||||||
"tourism", "government", "brewery"
|
"tourism", "government", "brewery"
|
||||||
];
|
];
|
||||||
public $tags_to_remove = ["diet:", "contact:", "name:", "payment:", "delivery:", "type:FR:", "ref:FR:SDIS:",
|
public $tags_to_remove = [
|
||||||
|
"diet:", "contact:", "name:", "payment:", "delivery:", "type:FR:", "ref:FR:SDIS:",
|
||||||
"brand:", "fuel:", "service:", "description:", "operator:", "tickets:", "healthcare:"
|
"brand:", "fuel:", "service:", "description:", "operator:", "tickets:", "healthcare:"
|
||||||
];
|
];
|
||||||
public $tags_to_convert = ["shop" => "was:shop",
|
public $tags_to_convert = [
|
||||||
|
"shop" => "was:shop",
|
||||||
"information" => "was:information",
|
"information" => "was:information",
|
||||||
"office" => "was:office",
|
"office" => "was:office",
|
||||||
"amenity" => "was:amenity",
|
"amenity" => "was:amenity",
|
||||||
|
@ -98,7 +101,7 @@ QUERY;
|
||||||
|
|
||||||
public function get_query_places($zone) {
|
public function get_query_places($zone) {
|
||||||
return '[out:json][timeout:25];
|
return '[out:json][timeout:25];
|
||||||
area["postal_code"="'.$zone.'"]->.searchArea;
|
area["ref:INSEE"="'.$zone.'"]->.searchArea;
|
||||||
'.$this->overpass_base_places.'
|
'.$this->overpass_base_places.'
|
||||||
out center tags;';
|
out center tags;';
|
||||||
}
|
}
|
||||||
|
@ -150,20 +153,9 @@ out center tags;';
|
||||||
|
|
||||||
public function labourer(string $zone): array
|
public function labourer(string $zone): array
|
||||||
{
|
{
|
||||||
|
|
||||||
$use_places_without_email_to_reference = $_ENV['USE_PLACES_WITHOUT_EMAIL_TO_REFERENCE'] ?? false;
|
|
||||||
|
|
||||||
if (!$zone) {
|
|
||||||
throw new \InvalidArgumentException("La zone ne peut pas être vide");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nettoyer et échapper la zone pour la requête
|
|
||||||
$zone = addslashes(trim($zone));
|
|
||||||
$query = $this->get_query_places($zone);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $this->client->request('POST', $this->overpassApiUrl, [
|
$response = $this->client->request('POST', $this->overpassApiUrl, [
|
||||||
'body' => ['data' => $query]
|
'body' => ['data' => $this->get_query_places($zone)]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$data = json_decode($response->getContent(), true);
|
$data = json_decode($response->getContent(), true);
|
||||||
|
@ -174,14 +166,6 @@ out center tags;';
|
||||||
if (isset($element['tags'])) {
|
if (isset($element['tags'])) {
|
||||||
|
|
||||||
$email = "";
|
$email = "";
|
||||||
if( ! $use_places_without_email_to_reference){
|
|
||||||
|
|
||||||
$email = $element['tags']['contact:email'] ?? $element['tags']['email'] ?? null;
|
|
||||||
// On passe si pas d'email
|
|
||||||
if (!$email) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$places[] = [
|
$places[] = [
|
||||||
'id' => $element['id'],
|
'id' => $element['id'],
|
||||||
|
@ -198,9 +182,6 @@ out center tags;';
|
||||||
|
|
||||||
return $places;
|
return $places;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
var_dump($query);
|
|
||||||
var_dump($e->getMessage());
|
|
||||||
die();
|
|
||||||
throw new \Exception("Erreur lors de la requête Overpass : " . $e->getMessage());
|
throw new \Exception("Erreur lors de la requête Overpass : " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,14 +189,14 @@ out center tags;';
|
||||||
public function get_city_osm_from_zip_code($zip_code) {
|
public function get_city_osm_from_zip_code($zip_code) {
|
||||||
// Requête Overpass pour obtenir la zone administrative de niveau 8 avec un nom
|
// Requête Overpass pour obtenir la zone administrative de niveau 8 avec un nom
|
||||||
$query = "[out:json][timeout:25];
|
$query = "[out:json][timeout:25];
|
||||||
area[\"postal_code\"=\"{$zip_code}\"]->.searchArea;
|
area[\"ref:INSEE\"=\"{$zip_code}\"]->.searchArea;
|
||||||
(
|
(
|
||||||
relation[\"admin_level\"=\"8\"][\"name\"][\"type\"=\"boundary\"][\"boundary\"=\"administrative\"](area.searchArea);
|
relation[\"admin_level\"=\"8\"][\"name\"][\"type\"=\"boundary\"][\"boundary\"=\"administrative\"](area.searchArea);
|
||||||
);
|
);
|
||||||
out body;
|
out body;
|
||||||
>;
|
>;
|
||||||
out skel qt;";
|
out skel qt;";
|
||||||
// $query = "area[\"postal_code\"=\"{$zip_code}\"]->.searchArea;";
|
|
||||||
$response = $this->client->request('POST', $this->overpassApiUrl, [
|
$response = $this->client->request('POST', $this->overpassApiUrl, [
|
||||||
'body' => ['data' => $query]
|
'body' => ['data' => $query]
|
||||||
]);
|
]);
|
||||||
|
@ -225,14 +206,12 @@ out center tags;';
|
||||||
return $city;
|
return $city;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_osm_object_data($osm_kind = 'node', $osm_object_id = 12855459190)
|
public function get_osm_object_data($osm_kind = 'node', $osm_object_id = 12855459190)
|
||||||
{
|
{
|
||||||
$object_id = "https://www.openstreetmap.org/api/0.6/".$osm_kind."/".$osm_object_id;
|
$object_id = "https://www.openstreetmap.org/api/0.6/".$osm_kind."/".$osm_object_id;
|
||||||
// dump($object_id);
|
|
||||||
// die();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $this->client->request('GET', $object_id);
|
$response = $this->client->request('GET', $object_id);
|
||||||
|
@ -308,6 +287,7 @@ out center tags;';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function migrate_tags($osm_object_data) {
|
public function migrate_tags($osm_object_data) {
|
||||||
|
|
||||||
// migrer email vers contact:email
|
// migrer email vers contact:email
|
||||||
|
@ -373,7 +353,7 @@ out center tags;';
|
||||||
$essentialTags = [
|
$essentialTags = [
|
||||||
'name',
|
'name',
|
||||||
'opening_hours',
|
'opening_hours',
|
||||||
// 'phone',
|
// 'phone',
|
||||||
'contact:email',
|
'contact:email',
|
||||||
'contact:phone',
|
'contact:phone',
|
||||||
'website',
|
'website',
|
||||||
|
|
|
@ -92,9 +92,9 @@
|
||||||
async function fetchland() {
|
async function fetchland() {
|
||||||
// Requête pour obtenir le contour administratif
|
// Requête pour obtenir le contour administratif
|
||||||
const boundaryQuery = `[out:json][timeout:25];
|
const boundaryQuery = `[out:json][timeout:25];
|
||||||
area["postal_code"="${zip_code}"]->.searchArea;
|
area["ref:INSEE"="${zip_code}"]->.searchArea;
|
||||||
(
|
(
|
||||||
relation["boundary"="postal_code"]["postal_code"="${zip_code}"](area.searchArea);
|
relation["boundary"="postal_code"]["ref:INSEE"="${zip_code}"](area.searchArea);
|
||||||
);
|
);
|
||||||
out body;
|
out body;
|
||||||
>;
|
>;
|
||||||
|
|
|
@ -25,20 +25,7 @@
|
||||||
|
|
||||||
|
|
||||||
// Fonction pour rechercher avec Addok
|
// Fonction pour rechercher avec Addok
|
||||||
async function searchPostalCode(query) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`https://api-adresse.data.gouv.fr/search/?q=${query}&type=municipality&autocomplete=1`);
|
|
||||||
const data = await response.json();
|
|
||||||
return data.features.map(feature => ({
|
|
||||||
label: `${feature.properties.city} (${feature.properties.postcode})`,
|
|
||||||
postcode: feature.properties.postcode,
|
|
||||||
city: feature.properties.city
|
|
||||||
}));
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erreur lors de la recherche:', error);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Créer et configurer la liste de suggestions
|
// Créer et configurer la liste de suggestions
|
||||||
const suggestionList = document.createElement('ul');
|
const suggestionList = document.createElement('ul');
|
||||||
|
@ -79,7 +66,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const suggestions = await searchPostalCode(query);
|
const suggestions = await searchInseeCode(query);
|
||||||
suggestionList.innerHTML = '';
|
suggestionList.innerHTML = '';
|
||||||
|
|
||||||
if (suggestions.length === 0) {
|
if (suggestions.length === 0) {
|
||||||
|
@ -135,12 +122,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Créer une carte des villes avec les codes postaux
|
// Créer une carte des villes avec les codes postaux
|
||||||
let map = new maplibregl.Map({
|
{# let map = new maplibregl.Map({
|
||||||
container: 'mapDashboard',
|
container: 'mapDashboard',
|
||||||
style: 'https://api.maptiler.com/maps/basic-v2/style.json?key={{ maptiler_token }}',
|
style: 'https://api.maptiler.com/maps/basic-v2/style.json?key={{ maptiler_token }}',
|
||||||
center: [2.3488, 48.8534], // Paris
|
center: [2.3488, 48.8534], // Paris
|
||||||
zoom: 10
|
zoom: 10
|
||||||
});
|
}); #}
|
||||||
|
|
||||||
// Fonction pour obtenir la couleur selon le pourcentage
|
// Fonction pour obtenir la couleur selon le pourcentage
|
||||||
function getColorFromPercent(percent) {
|
function getColorFromPercent(percent) {
|
||||||
|
@ -232,9 +219,15 @@ out skel qt;`;
|
||||||
|
|
||||||
<h2>{{ places_count }} Lieux</h2>
|
<h2>{{ places_count }} Lieux</h2>
|
||||||
<h2><button class="btn btn-primary" id="labourer">Labourer les mises à jour</button></h2>
|
<h2><button class="btn btn-primary" id="labourer">Labourer les mises à jour</button></h2>
|
||||||
<label for="app_admin_labourer">Rechercher une ville </label>
|
<label for="app_admin_labourer">Rechercher une ville par son nom
|
||||||
<input class="form-control" type="text" id="app_admin_labourer" value="75013">
|
<div id="loading_search_insee" class="d-none">
|
||||||
|
<div class="spinner-grow text-primary" role="status">
|
||||||
|
<span class="sr-only">Chargement...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<input class="form-control" type="text" id="app_admin_labourer" placeholder="Entrez le nom d'une ville...">
|
||||||
|
<div id="suggestionList" class="suggestion-list"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -170,27 +170,28 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block javascripts %}
|
|
||||||
{{ parent() }}
|
|
||||||
<script src={{asset('js/mapbox/mapbox-gl.js')}}></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
|
|
||||||
{% if commerce is not empty and mapbox_token is not empty and maptiler_token is not empty and commerce_overpass['@attributes'].lon is defined and commerce_overpass['@attributes'].lat is defined %}
|
|
||||||
mapboxgl.accessToken = '{{ mapbox_token }}';
|
|
||||||
map = new mapboxgl.Map({
|
|
||||||
container: 'map',
|
|
||||||
style: 'https://api.maptiler.com/maps/basic-v2/style.json?key={{ maptiler_token }}',
|
|
||||||
center: [{{ commerce_overpass['@attributes'].lon }}, {{ commerce_overpass['@attributes'].lat }}],
|
|
||||||
zoom: 17
|
|
||||||
});
|
|
||||||
|
|
||||||
new mapboxgl.Marker()
|
|
||||||
.setLngLat([{{ commerce_overpass['@attributes'].lon }}, {{ commerce_overpass['@attributes'].lat }}])
|
|
||||||
.setPopup(new mapboxgl.Popup({ offset: 25 }).setHTML('<h1>{{ commerce_overpass.tags_converted.name }}</h1>'))
|
|
||||||
.addTo(map);
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block javascripts %}
|
||||||
|
{{ parent() }}
|
||||||
|
<script src={{asset('js/mapbox/mapbox-gl.js')}}></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
{% if commerce is not empty and mapbox_token is not empty and maptiler_token is not empty and commerce_overpass['@attributes'].lon is defined and commerce_overpass['@attributes'].lat is defined %}
|
||||||
|
mapboxgl.accessToken = '{{ mapbox_token }}';
|
||||||
|
map = new mapboxgl.Map({
|
||||||
|
container: 'map',
|
||||||
|
style: 'https://api.maptiler.com/maps/basic-v2/style.json?key={{ maptiler_token }}',
|
||||||
|
center: [{{ commerce_overpass['@attributes'].lon }}, {{ commerce_overpass['@attributes'].lat }}],
|
||||||
|
zoom: 17
|
||||||
|
});
|
||||||
|
|
||||||
|
new mapboxgl.Marker()
|
||||||
|
.setLngLat([{{ commerce_overpass['@attributes'].lon }}, {{ commerce_overpass['@attributes'].lat }}])
|
||||||
|
.setPopup(new mapboxgl.Popup({ offset: 25 }).setHTML('<h1>{{ commerce_overpass.tags_converted.name }}</h1>'))
|
||||||
|
.addTo(map);
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue