Skip to content

Commit e52ebae

Browse files
committed
Merge branch 'feature/search-refonte' of https://github.com/IGNF/geopf-extensions-openlayers into feature/search-refonte
# Conflicts: # src/packages/Controls/SearchEngine/ParcelAdvancedSearch.js
2 parents ca437e6 + cc28320 commit e52ebae

File tree

6 files changed

+127
-35
lines changed

6 files changed

+127
-35
lines changed

src/packages/CSS/Controls/SearchEngine/DSFRsearchEngineStyle.css

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,17 @@ div[id^=GPgeocodeResults-] {
308308
box-shadow: 0 -1px 0 0 var(--border-default-grey);
309309
}
310310

311+
[id^="GPsearchEngine"] ul li.GPsearchHistoric {
312+
padding-right: 1.75rem;
313+
}
314+
315+
[id^="GPsearchEngine"] ul li.GPsearchHistoric > span {
316+
position: absolute;
317+
right: 1rem;
318+
color: var(--grey-625-425);
319+
}
320+
311321
[id^="GPsearchEngine"] ul li:first-child {
312-
padding: 0.75rem 0.5rem;
313-
color: var(--text-action-high-grey);
314322
box-shadow: none;
315323
}
316324

@@ -410,4 +418,10 @@ form.GPSearchBar > .GPInputGroup > input[data-empty] ~ .GPOptionsContainer > but
410418

411419
form.GPSearchBar > .GPInputGroup > input[data-empty] ~ .GPOptionsContainer > button[id^="GPSearchEngine-advanced-btn"] {
412420
display:none;
421+
}
422+
423+
.fr-icon-ign-mer::before,
424+
.fr-icon-ign-mer::after {
425+
-webkit-mask-image: url("./img/dsfr/ign-mer.svg");
426+
mask-image: url("./img/dsfr/ign-mer.svg");
413427
}
Lines changed: 5 additions & 0 deletions
Loading

src/packages/Controls/SearchEngine/SearchEngineAdvanced.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class SearchEngineAdvanced extends Control {
187187
// Focus sur le bouton de recherche avancée
188188
this.advancedBtn.focus();
189189
} else {
190-
this.baseSearchEngine.subimtBt.focus();
190+
this.eraseBtn.focus();
191191
}
192192
}
193193
}.bind(this));
@@ -337,6 +337,8 @@ class SearchEngineAdvanced extends Control {
337337
eraseBtn.addEventListener("click", function () {
338338
this.baseSearchEngine.input.value = "";
339339
delete this.baseSearchEngine.input.dataset.empty;
340+
// Notifie l'input du changement
341+
this.baseSearchEngine.input.dispatchEvent(new Event("input"));
340342
}.bind(this));
341343
this.baseSearchEngine.optionscontainer.appendChild(eraseBtn);
342344
}

src/packages/Controls/SearchEngine/SearchEngineBase.js

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import Helper from "../../Utils/Helper";
77

88
// Voir les typedefs partagés dans ./typedefs.js (SearchEngineBaseOptions, SearchServiceOptions, ...)
99

10+
const history = "fr-icon-history-line";
1011
const typeClasses = {
11-
"history" : "fr-icon-history-line",
12-
"search" : "fr-icon-map-pin-2-line",
12+
"StreetAddress" : "fr-icon-map-pin-2-line",
13+
"PositionOfInterest" : {
14+
"administratif" : "fr-icon-france-fill",
15+
"hydrographie" : "fr-icon-ign-mer",
16+
"default" : "fr-icon-map-pin-2-line",
17+
}
1318
};
1419

1520
var logger = Logger.getLogger("searchengine");
@@ -174,18 +179,9 @@ class SearchEngineBase extends Control {
174179
// Réaffiche la valeur précédente de l'utilisateur
175180
e.target.value = this._previousValue;
176181
}
177-
break;
178-
case "Enter":
179-
// Lance la recherche
180-
let item = list[idx];
181-
if (idx < 0) {
182-
// Pas d'item sélectionné : on prend le premier de la liste
183-
item = list[0];
184-
}
185-
if (item) {
186-
// Simule un clic sur l'élément sélectionné
187-
item.click();
188-
}
182+
// Envoie un événement de type input pour notifier le changement
183+
this.input.dispatchEvent(new Event("input"));
184+
189185
break;
190186
default:
191187
if (e.target.value.length && e.target.value.length >= options.minChars && e.target.value !== this._currentValue) {
@@ -500,14 +496,22 @@ class SearchEngineBase extends Control {
500496
this.input.setAttribute("data-active-option", "");
501497
// Update list
502498
this.autocompleteList.innerHTML = "";
503-
const iconClass = typeClasses[type] || typeClasses["search"];
504499
tab.forEach((item, idx) => {
505500
const li = document.createElement("li");
506-
li.id = Helper.getUid("GPsearchHistoric-");
507-
li.className = `GPsearchHistoric gpf-panel__item gpf-panel__item-searchengine ${iconClass} fr-icon--sm`;
501+
const iconClass = this.getIconClass(item, type);
502+
503+
li.id = Helper.getUid("GPsearchResult-");
504+
li.className = `GPsearchResult gpf-panel__item gpf-panel__item-searchengine ${iconClass} fr-icon--sm`;
508505
li.setAttribute("role", "option");
509506
li.setAttribute("data-idx", idx);
510507
li.innerHTML = li.title = this.getItemTitle(item);
508+
if (type === "history") {
509+
li.classList.add("GPsearchHistoric");
510+
const span = document.createElement("span");
511+
span.ariaHidden = "true";
512+
span.className = `${history} fr-icon--sm`;
513+
li.append(span);
514+
}
511515
this.autocompleteList.appendChild(li);
512516
li.addEventListener("click", function (e) {
513517
const idx = Number(e.target.getAttribute("data-idx"));
@@ -519,6 +523,30 @@ class SearchEngineBase extends Control {
519523
});
520524
}
521525

526+
/**
527+
* Retourne la classe à ajouter pour un résultat d'autocomplétion
528+
* @param {AutocompleteResult} item Résultat de l'autocomplétion (ou historique)
529+
* @param {String} type Type de la recherche ("history" ou "search")
530+
* @returns {String} classe à ajouter
531+
*/
532+
getIconClass (item, type) {
533+
// let iconClass = typeClasses[type];
534+
let iconClass = typeClasses[item.type];
535+
// Cas où l'on a d'autres éléments
536+
if (typeof iconClass === "object") {
537+
// Cherche les types de POI
538+
for (let i = 0; i < item.poiType.length; i++) {
539+
const poiType = item.poiType[i];
540+
if (Object.hasOwn(iconClass, poiType)) {
541+
iconClass = iconClass[poiType];
542+
break;
543+
}
544+
}
545+
iconClass = typeof iconClass === "object" ? iconClass["default"] : iconClass;
546+
}
547+
return iconClass;
548+
}
549+
522550
/**
523551
* Retourne le titre à afficher pour un item.
524552
* @param {Object} item Élément à afficher

src/packages/Services/IGNSearchService.js

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import GeocodeUtils from "../Utils/GeocodeUtils";
1010
import Search from "./Search";
1111
import Feature from "ol/Feature.js";
1212
import Point from "ol/geom/Point.js";
13-
import { canvasPool } from "ol/renderer/canvas/Layer";
1413

1514
var logger = Logger.getLogger("searchengine");
1615

16+
// logger.log = () => { };
1717

1818
/**
1919
* @classdesc
@@ -72,11 +72,11 @@ class IGNSearchService extends AbstractSearchService {
7272
autocomplete : true,
7373
autocompleteOptions : {
7474
serviceOptions : {
75-
maximumResponses : 5,
75+
maximumResponses : 10,
7676
},
7777
triggerGeocode : false,
7878
triggerDelay : 1000,
79-
prettifyResults : false
79+
prettifyResults : true
8080
},
8181
};
8282

@@ -137,8 +137,6 @@ class IGNSearchService extends AbstractSearchService {
137137
* @type {Array<AutocompleteResult>}
138138
*/
139139
this._suggestedLocations;
140-
141-
console.log(this.options);
142140
}
143141

144142

@@ -332,8 +330,8 @@ class IGNSearchService extends AbstractSearchService {
332330
* @private
333331
*/
334332
_prettifyAutocompleteResults (autocompleteResults) {
335-
for (var i = autocompleteResults.length - 1; i >= 0; i--) {
336-
var autocompleteResult = autocompleteResults[i];
333+
for (let i = autocompleteResults.length - 1; i >= 0; i--) {
334+
const autocompleteResult = autocompleteResults[i];
337335
if ((autocompleteResult.type === "StreetAddress" && autocompleteResult.kind === "municipality") ||
338336
autocompleteResult.type === "PositionOfInterest" && autocompleteResult.poiType[0] === "lieu-dit habité" && autocompleteResult.poiType[1] === "zone d'habitation") {
339337
// on retire les éléments streetAdress - municipality car déjà pris en compte par POI
@@ -400,37 +398,82 @@ class IGNSearchService extends AbstractSearchService {
400398
/**
401399
* Lance une recherche sur les services de géocodage de l'IGN
402400
* @see {@link https://data.geopf.fr/geocodage/search}
401+
* @see {@link https://data.geopf.fr/geocodage/openapi}
403402
* @param {IGNSearchObject} object Recherche
404403
* @abstract
405404
*/
406405
search (object) {
407406
const location = object.location;
408-
const filters = object.filters;
407+
const filters = object.filters ? object.filters : {};
409408

410409
if (location === undefined) {
411410
return;
412411
}
413412
// on ajoute le texte de l'autocomplétion dans l'input
414413
let label;
414+
let index = this.get("index");
415+
let truegeometry = this.get("returnTrueGeometry");
415416
if (typeof location === "string") {
417+
// Location est un texte, on prend les valeurs par défaut
416418
label = location;
417419
} else {
420+
// location est un objet : on vérifie les informations qu'il comporte
421+
422+
// Récupère les infos (s'il y'en a)
423+
index = location.type ? location.type : index;
418424
label = GeocodeUtils.getSuggestedLocationFreeform(location);
419-
}
425+
// TODO : AMÉLIORER CETTE PARTIE (REDONDANTE)
426+
// Enlève l'ajout du prettify
427+
if ((location.type === "PositionOfInterest" && location.poiType[0] === "administratif" &&
428+
(location.poiType[1] === "département" || location.poiType[1] === "région"))) {
429+
label = label.substring(0, label.length - (location.poiType[1].length + 2));
430+
}
420431

421-
// on sauvegarde le localisant
422-
this._currentGeocodingLocation = label;
432+
if (index === "PositionOfInterest") {
433+
// Recherche d'un POI : ajout d'infos supplémentaires
434+
let poiType = location.poiType[0];
435+
if (poiType === "administratif" && location.poiType[1]) {
436+
poiType = location.poiType[1];
437+
}
438+
filters.category = poiType ? poiType : null;
439+
440+
// Retourne la géométrie pour certains types seulement
441+
truegeometry = false;
442+
const trueGeometries = ["administratif", "département", "construction", "hydrographie"];
443+
for (let i = 0; i < location.poiType.length; i++) {
444+
const type = location.poiType[i];
445+
if (type !== "lieu-dit habité" && trueGeometries.includes(type)) {
446+
truegeometry = true;
447+
break;
448+
}
449+
}
450+
}
451+
filters.postalCode = location.postalCode ? location.postalCode : null;
452+
453+
// Retire chaque valeurs nulles
454+
for (const key in filters) {
455+
if (!Object.hasOwn(filters, key)) {
456+
continue;
457+
};
458+
if (filters[key] === null) {
459+
delete filters[key];
460+
}
461+
}
462+
}
423463

424464
// on centre la vue et positionne le marker, à la position reprojetée dans la projection de la carte
465+
425466
this._requestGeocoding({
426-
index : this.get("index"),
467+
index : index,
427468
limit : this.get("limit"),
428-
returnTrueGeometry : this.get("returnTrueGeometry"),
469+
returnTrueGeometry : truegeometry,
429470
location : label,
430471
filters : filters,
431472
onSuccess : this._onSuccessSearch.bind(this),
432473
onFailure : this._onFailureSearch.bind(this, location),
433474
});
475+
// on sauvegarde le localisant
476+
this._currentGeocodingLocation = label;
434477
}
435478

436479

src/packages/Services/typedefs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
* @typedef {Object} IGNSearchObject
4949
* @property {AutocompleteResult|String} location - Objet utilisé pour faire la requête.
5050
* Peut être soit le résultat de l'autocomplétion ou une chaîne de caractère.
51-
* @property {IGNSearchFilter} [filter] - Filtres optionnels pour
51+
* @property {IGNSearchFilter} [filters] - Filtres optionnels pour la recherche
5252
*/
5353

5454
/**
@@ -57,7 +57,7 @@
5757
* @typedef {Object} IGNSearchFilter
5858
* @property {string} [postalCode] - Code postal (adresses, toponymes).
5959
* @property {string} [inseeCode] - Code INSEE (adresses, toponymes).
60-
* @property {string} [city] - Nom de la ville (adresses uniquement).
60+
* @property {string} [city] - Nom de la ville (adresses, toponymes).
6161
* @property {string} [type] - Type de toponyme (toponymes uniquement).
6262
* @property {string} [codeDepartement] - Code département (parcelles cadastrales uniquement).
6363
* @property {string} [codeCommune] - Code commune (parcelles cadastrales uniquement).

0 commit comments

Comments
 (0)