Icônes de carte personnalisées via chargement direct des svg
publié le , mis à jour⚙️ Ceci est une proposition de changement de code.
Rendez-vous sur sa page Coderberg pour l'osculter.
Salut, Cette PR est une proposition alternative à la PR #776, qui proposait d'utiliser spritezero pour créer un couple png/json décrivant les icones créées à partir de tous les svg des catégories. A la place, cette PR propose :
- de charger directement les svg dans la carte
- de tenter en premier d'utiliser ces images comme icones pour les POI (sinon fallback vers sprites d'origine, sinon fallback vers sprites d'indoorequal pour les items spécifiques à indoorequal)
Avant cette PR :
Après cette PR :
etienneJr
Si cette PR est acceptée, il faudra ensuite :
- harmoniser les ID entre nos svg et les class/subclass du pmtiles. Par exemple pour que l'icone
beers'affiche sur lesbar - réfléchir à comment mieux distinguer les POI sélectionnés par catégorie des POI affichés sur le fond de carte. Pour l'instant il n'y a qu'une différence de taille d'icone, plus le petit point rouge/vert/vide. (cette question visuelle est identique avec l'autre solution).
- [edit] : supprimer le rechargement des icones lors de l'affichage des POI par catégorie pour utiliser celles déjà présentes.
- harmoniser les ID entre nos svg et les class/subclass du pmtiles. Par exemple pour que l'icone
laem
Merci, PR très intéressante qui évite en effet de générer des sprites, comme discuté ici /documentation/tickets/613#issuecomment-2631706477
laem
Un bug trouvé : Quand la catégorie sur les données des tuiles est "shop", il va prendre l'icône shop.svg qui est orange car utilisé dans Alimentation. Or, c'est pas cohérent, shop est bien plus large. Exemple ici avec un magasin de cigelec http://localhost:8080/?cat-plus=oui&allez=Le+petit+vapoteur%7Cn2108970009%7C6.1770%7C49.1175#18/49.1175/6.177/15/40
Ça rentre dans ton point 1). Je vais réfléchir à comment faire ça.
Il y a une liste des attributs class et subclass de OMT, le schéma qu'on utilise avec quelques extensions, ici https://openmaptiles.org/schema/#poi
En fait si je comprends bien, tous les icônes qui marchent sur ta capture le font grâce au pseudo-hasard d'un même nommage entre nos icônes .svg et les attributs OMT.
Je suis moins inquet pour le point 2, c'est facile à faire, juste un peu de style.
etienneJr
tous les icônes qui marchent sur ta capture le font grâce au pseudo-hasard d'un même nommage entre nos icônes .svg et les attributs OMT.
Oui tout à fait, du pur hasard, vu que je n'ai pas pris le temps de comparer en amont les attributs OpenMapTiles et nos catégories 😬 Mais je compte bien le faire dans les prochains jours si ça te va ?
c'est pas cohérent, shop est bien plus large.
Donc on est d'accord que le défaut vient du fait que le schéma OMT n'est pas assez détaillé à notre goût ? (et donc que ça aurait été pareil avec les sprites png ?). Je sens clairement qu'il va falloir adapter le schéma OMT pour inclure dans les tuiles un peu plus de précisions (genre shop alimentaire VS shop autre) mais on ne va pas non plus reconstruire dans les tuiles toute la diversité de nos catégories ? il va falloir trouver un juste équilibre ... Est-ce que ça aiderait de générer 2 fichiers distincts ? Un fichier avec les tuiles au strict schéma OMT mais sans les POIs, et un fichier avec juste les POIs dans un schéma perso plus détaillé correspondant à nos catégories ?
laem
Donc on est d'accord que le défaut vient du fait que le schéma OMT n'est pas assez détaillé à notre goût ? (et donc que ça aurait été pareil avec les sprites png ?).
Non pas complètement. restaurant et shop sont distincts dans OMT, donc c'est gérable. Par contre dans l'absolu c'est sûr que pour pouvoir donner un icône différent entre un vendeur de cigarettes.
Mais tu vois :
class: "shop" "name:fr": "the phone service" subclass: "copyshop"
Ou encore
class: "shop" indoor: false layer: 0 "name:fr": "Warhammer" nwr: "n" rank: 18 subclass: "games"
C'est suffisamment précis pour faire un premier lot de belles icônes colorées.
laem
Je m'y mets là maintenant.
GhostDokploy Preview Deployment
Name Status Preview Updated (UTC) web-master ✅ Done Preview URL 2025-02-09T23:14:41.902Z laem
- créer un nouvel attribut "icon name" pour créer à partir d'un même fichier svg ("icon") une nouvelle image sur maplibre avec un autre nom, pour permettre d'avoir plusieurs images identiques avec des fonds différents et correspondres aux class OMT
Bon, nouveau problème : les appels lancés à /svgo pour créer les SVG imposent un temps d'attente assez long pour générer une page.
laem
Bon, nouveau problème : les appels lancés à /svgo pour créer les SVG imposent un temps d'attente assez long pour générer une page.
Je vais le résoudre en transformant /svgo pour renvoyer l'équivalent d'un sprite mais en SVG.
laem
Reste un pb : le style est chargé, puis ensuite les images sont ajoutées. Ainsi au niveau de zoom initial, ce sont les sprites qui sont utilisées...
laem
OK, j'arrive pas à faire recharger la carte après avoir ajouté les icônes, c'est terrible, il semble y avoir un conflit avec les sprites. Je tente une autre stratégie : remplacer tous les sprites :sweat_smile:
C'est un super moyen de voir quelles catégories sont manquantes. J'ai déjà ajouté parking voiture, théâtre...
etienneJr
Bon, nouveau problème : les appels lancés à /svgo pour créer les SVG imposent un temps d'attente assez long pour générer une page.
Euh, il y a une raison pour faire recalculer les même svg à chaque génération de la page par l'utilisateur ? C'est parce que tu anticipes une personnalisation de l'app pour chaque utilisateur ? Parce que sinon, tant qu'ils sont pareils pour tout le monde, il vaudrait mieux qu'ils soient (pré)calculés par le serveur une bonne fois pour toutes, non ? (avec mise à jour à chaque déploiement par exemple)
Et il y a peut-être une autre option pour se passer de /svgo : charger directement le svg tels que disponibles, et ajouter le cercle de couleur grâce à la feuille de style maplibre ?
etienneJr
je n'ai pas pris le temps de comparer en amont les attributs OpenMapTiles et nos catégories 😬 Mais je compte bien le faire dans les prochains jours si ça te va ?
Voilà, c'est fait : https://github.com/cartesapp/cartes/wiki/OpenMapTiles-VS-icons
- Il y a en effet déjà beaucoup de valeurs possibles dans le schéma OMT, je n'avais pas conscience de ça
- J'ai identifié un paquet d'icones qu'il faudrait renommer pour qu'elles soient compatibles avec OMT
- et ça permet d'identifier quelles icones il faudrait créer pour compléter notre set d'icones (même si on ne les utilise pas dans nos catégories), notamment en regardant leur usage dans taginfo (cf rubrique office pour laquelle j'ai fait ça)
etienneJr
créer un nouvel attribut "icon name" pour créer à partir d'un même fichier svg ("icon") une nouvelle image
Est-ce qu'il ne faudrait pas différencier la création des icones du listing des catégories ? C'est à dire avoir
- d'une part (comme avant) la liste des catégories avec leurs proprités
icon - d'autre part une liste plus générale, qui est lue pour créer les icones à partir des svg d'origine, avec possiblement plusieurs icones à partir d'un même svg pour avoir
- différents fonds
- différents ID
- et pour différents usages (catégories, tuiles, seo, ...)
- d'une part (comme avant) la liste des catégories avec leurs proprités
laem
Euh, il y a une raison pour faire recalculer les même svg à chaque génération de la page par l'utilisateur ? C'est parce que tu anticipes une personnalisation de l'app pour chaque utilisateur ? Parce que sinon, tant qu'ils sont pareils pour tout le monde, il vaudrait mieux qu'ils soient (pré)calculés par le serveur une bonne fois pour toutes, non ? (avec mise à jour à chaque déploiement par exemple)
Les appels d'API Next comme /svgo/bulk que je viens de créer sont mis en cache ou du moins très faciles à mettre en cache. Donc pas de souci de ce point de vue. On peut en effet précompiler par la suite quand il y a des changements d'icônes mais il faut y penser à chaque fois.
laem
et ça permet d'identifier quelles icones il faudrait créer pour compléter notre set d'icones (même si on ne les utilise pas dans nos catégories), notamment en regardant leur usage dans taginfo (cf rubrique office pour laquelle j'ai fait ça)
Merci ! C'est complémentaire avec ce que j'ai fait dans le code : un log des images maplibre qui manquent, au runtime.
const onImageMissing = (e) => { const id = e.id // id of the missing image console.log('imagemissing', id) }laem
d'autre part une liste plus générale, qui est lue pour créer les icones à partir des svg d'origine, avec possiblement plusieurs icones à partir d'un même svg pour avoir [...]
Oui c'est plus ou moins ce que j'ai fait grâce au nouvel attribut "icon name" dans les categories yaml, et grâce au nouveau fichier imageRedirects.yaml :)
laem
Je continue la complétion des icônes ce matin.
laem
Mince @etienneJr je viens de voir que je poussais sur une branche au même nom dans cartesapp, plutôt que sur ton fork :/ Du coup tu n'as peut-être pas vu mes travaux.
J'en suis là 55c400f1d79db1d17b418d0310e000b190a86d3e
Pour l'instant j'y vais un peu bourrin à ajouter des icônes ou des transcriptions dans "redirects" mais par la suite je vérifierai que tout fonctionne bien.
Ça avance bien :)
laem
- ajouter les icônes de feu https://cartes.app/sprite/sprite@2x.png pour au moins couvrir l'existant
- donner un style différent aux recherches par catégories <-- fait avec une taille plus importante, mais dans une 1ère version approximative, à calibrer
- charger en bloc les images des catégories
etienneJr
je viens de voir que je poussais sur une branche au même nom dans cartesapp, plutôt que sur ton fork :/ Du coup tu n'as peut-être pas vu mes travaux.
Hum, j'ai l'impression que les 2 branches sont synchronisées. Quand tu pousses un commit dans
cartesapp:poi-sprites-using-svgil apparait aussi dansetienneJr:poi-sprites-using-svg. Et ungit pulldans mon fork rappatrie immédiatement tous tes commits, donc c'est pas un problème. Mais bon de toute façon je n'ai pas du tout eu le temps de regarder plus tôt ...[EDIT] j'ai même l'impression que
cartesapp:poi-sprites-using-svgest un alias pouretienneJr:poi-sprites-using-svgcar quand je consulte les fichiers de tes commits j'ai ce warningex : https://github.com/cartesapp/cartes/blob/b1f29932972f28644754d463629e98a744397411/app/svgo/route.ts
etienneJr
Les appels d'API Next comme /svgo/bulk que je viens de créer sont mis en cache ou du moins très faciles à mettre en cache.
Donc ça résoud ton problème de temps d'attente trop long au chargement de la page ?
etienneJr
nouveau fichier imageRedirects.yaml
Bonne idée ! Je me demande juste : comme on utilise
addImage(ImageData), ça veut dire que ça rajoute des images supplémentaires, au contenu strictement identique à celui d'autres images ? Bon c'est peut-être pas très grave. D'autant que je ne saurais pas dire siaddImage(HTMLImageElement)aurait créé un alias ou lui aussi recopié le contenu.etienneJr
Je tente une autre stratégie : remplacer tous les sprites 😅
euh ouais ça me parait bizarre comme idée ! Il y a quand même beaucoup des sprites dans feu sprite.png ! Dont pas mal qu'on aurait bien gardés tels quels non ? Quid des encarts pour les numéros de route par ex ? Le fallback me paraissait quand même plus pratique.
etienneJr
Reste un pb : le style est chargé, puis ensuite les images sont ajoutées. Ainsi au niveau de zoom initial, ce sont les sprites qui sont utilisées...
J'ai pas suivi tous tes tests. Au final, ce qui pose pb avec le fallback, c'est "juste" d'arriver à charger les images svg suffisament vite pour qu'on ne voit pas les sprites du fallback avant ? Perso, si c'est assez rapide ça ne me choque pas. (voire ça fait un effet wahoo quand les icones colorées apparaissent :smile: )
[EDIT] j'ai regardé la version actuelle, en effet les icones mettent trop de temps à s'afficher. Hélas, je ne gère pas du tout react/nextjs donc je n'ai rien à proposer. Mais ce lag ne sera pas corrigé par la mise en cache dont tu as parlé ?
Et je remarque qu'il y a toujours le bug que j'ai depuis le début : si on change de style de carte puis qu'on revient au style france, alors les icones ne s'affichent pas.
et puis dès le départ j'ai des icones qui s'affichent plus grandes que d'autres (identiques) sans que j'ai choisi une catégorie, bizarre ?
http://localhost:8080/#18.24/48.104654/-1.681275
laem
Bonne idée ! Je me demande juste : comme on utilise addImage(ImageData), ça veut dire que ça rajoute des images supplémentaires, au contenu strictement identique à celui d'autres images ? Bon c'est peut-être pas très grave. D'autant que je ne saurais pas dire si addImage(HTMLImageElement) aurait créé un alias ou lui aussi recopié le contenu.
J'ai pas vu de pb de perf et je suis relativement convaincu qu'en interne dans maplibre sprite.png est avalé via une suite de addImage. On pourrait creuser si pb de perf arrivent.
euh ouais ça me parait bizarre comme idée ! Il y a quand même beaucoup des sprites dans feu sprite.png ! Dont pas mal qu'on aurait bien gardés tels quels non ? Quid des encarts pour les numéros de route par ex ? Le fallback me paraissait quand même plus pratique.
En fait pas tant ! D'une poru les routes elles sont bien trop focalisées sur les routes voiture et surtout étatsunienne, donc hors jeu ici, et de deux, je trouve important de maitriser l'aspect visuel de ces éléments si fréquents sur les cartes.
Ce que je te propose, c'est de monitorer les images manquantes. En quelques jours on saura ce qu'il faut gérer... notamment des icônes manquantes dans le sprite actuel, j'en ai déjà repéré.
laem
Normalement pour la taille des icônes c'est réglé. Mais oui, pour le reste, faut corriger ces bugs merci.
Edit : pour la disparition c'est fait.
laem
Je n'ai jamais réussi à collaborer sur la branche d'un fork extérieur malgré mes efforts. Donc là je bosse sur https://github.com/cartesapp/cartes/commits/poi-sprites-using-svg
laem
Je mets en ligne : mon log des images manquantes est en place, ça permettra de corriger les pb de cette branche et de repérer les icônes manquantes dans l'absolu :)
laem
Merci pour ton travail !
laem
Voilà ça fonctionne. Peut-être qu'il faudra faire quelques ajustements.
Le code du serveur est dans cartesapp/cartes-deno