Mapsui 5 introduit une rupture importante dans la façon dont les images sont gérées. Si tu migres depuis la version 4, tu as sûrement rencontré des erreurs liées à BitmapId, BitmapRegistry ou SymbolStyle, des APIs désormais obsolètes ou supprimées. Cet article fait le point sur le nouveau système, et montre comment l’utiliser concrètement pour afficher des pins personnalisés sur une carte .NET MAUI.
Le nouveau système d’images dans Mapsui 5
Avant la version 5, afficher une image personnalisée sur la carte nécessitait de charger manuellement le bitmap, de l’enregistrer dans un BitmapRegistry, de récupérer un BitmapId entier, et de l’affecter à un SymbolStyle. C’était fonctionnel, mais verbeux et peu intuitif.
Mapsui 5 simplifie tout ça avec un système basé sur des URI de type chaîne. Tu spécifies l’image via une simple propriété string, et Mapsui s’occupe du chargement, du cache et du rendu. Plus besoin de gérer le cycle de vie des bitmaps manuellement.
Ce système est unifié : il s’applique aussi bien aux Pin, aux ImageStyle, aux ButtonWidget, etc.
Les cinq schémas d’URI supportés
Mapsui 5 supporte cinq façons de référencer une image.
1. https:// ou http:// image distante
L’image est téléchargée depuis un serveur distant. Pratique pour des icônes dynamiques ou hébergées, mais dépend de la connectivité réseau.
pin.ImageSource = "<a href="https://example.com/icons/mymarker.png"">https://example.com/icons/mymarker.png"</a>;
2. file:// fichier local
Pointe vers un fichier présent sur le système de fichiers de l’appareil. Utile pour des images téléchargées ou générées à l’exécution.
var localPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
pin.ImageSource = $"file://{localPath}/icons/mymarker.png";
3. embedded:// ressource embarquée dans l’assembly
C’est le schéma le plus courant pour des images packagées avec l’application. L’image doit être une ressource embarquée .NET classique (voir la section sur le piège MAUI plus bas).
pin.ImageSource = "embedded://MonApp.Resources.Images.mymarker.svg";
Le format du chemin suit la convention .NET pour les ressources embarquées : NomAssembly.Dossier.SousDossier.fichier.ext, avec des points comme séparateurs.
4. svg-content:// SVG inline
Permet de passer directement le contenu XML d’un SVG sous forme de chaîne. Très utile pour des icônes générées dynamiquement ou pour éviter de gérer des fichiers séparés.
var svgContent = """
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36">
<circle cx="18" cy="18" r="16" fill="#E63946"/>
</svg>
""";
pin.ImageSource = $"svg-content://{svgContent}";
5. base64-content:// image encodée en base64
Permet d’intégrer n’importe quelle image (PNG, JPEG, SVG…) directement dans la chaîne, sans fichier externe. Idéal quand l’image provient d’une API, d’une base de données, ou quand tu veux éviter tout problème de chemin.
byte[] imageBytes = File.ReadAllBytes("mymarker.png");
string base64 = Convert.ToBase64String(imageBytes);
pin.ImageSource = $"base64-content://{base64}";
Utiliser PinType.ImageSource en pratique
L’objet Pin de Mapsui.UI.Maui expose une propriété Type de type PinType. Quand cette valeur est PinType.ImageSource, Mapsui utilise directement la propriété ImageSource pour rendre l’icône. Si ImageSource est null ou vide, une InvalidOperationException est levée au moment du rendu.
Voici un exemple complet :
var pin = new Pin
{
Label = "Mon point d'intérêt",
Position = new Position(45.188, 5.724),
Type = PinType.ImageSource,
ImageSource = "embedded://MonApp.Resources.Images.mymarker.svg",
Scale = 1.0f,
IsVisible = true
};
mapView.Pins.Add(pin);
Si tu veux utiliser une couleur de teinte (blending) sur l’icône, note que cela n’est disponible qu’avec PinType.Pin (le pin SVG intégré de Mapsui). Avec PinType.ImageSource, l’image est rendue telle quelle.
⚠️ Le piège MAUI : EmbeddedResource vs MauiImage
C’est le point qui fait perdre le plus de temps lors d’une migration vers Mapsui 5 sur .NET MAUI.
Dans un projet MAUI, les images placées dans Resources/Images ont par défaut la Build Action MauiImage. Cette action de compilation les transforme et les intègre dans les ressources natives de chaque plateforme (Android drawable, iOS asset catalog, etc.). Elles ne sont pas accessibles comme ressources embarquées .NET.
Le schéma embedded:// de Mapsui attend des ressources embarquées .NET classiques, c’est-à-dire des fichiers compilés avec la Build Action EmbeddedResource.
Ce qu’il faut faire :
- Ajouter l’image à ton projet (par exemple dans un dossier
Assets/Icons/) - Dans les propriétés du fichier, changer la Build Action de
MauiImageàEmbeddedResource - Utiliser le chemin complet avec le nom de l’assembly
Comment trouver le nom exact de la ressource ?
Le nom généré peut varier selon la structure de ton projet. Pour le trouver avec certitude, utilise ce snippet au démarrage de l’application :
var names = System.Reflection.Assembly .GetExecutingAssembly() .GetManifestResourceNames(); foreach (var name in names) System.Diagnostics.Debug.WriteLine(name);
Tu verras dans la console de débogage des noms du type :
MonApp.Assets.Icons.mymarker.svgMonApp.Assets.Icons.otherpoi.png
C’est exactement ce que tu dois passer à embedded://.
Quelle alternative si embedded:// pose problème ?
Si tu ne veux pas te soucier des Build Actions ou de la structure de ressources, le schéma base64-content:// est une excellente alternative. Tu charges l’image une seule fois (depuis un stream, une ressource MauiImage via ImageSource, une API…), tu l’encodes en base64, et tu passes la chaîne directement.
C’est légèrement moins élégant mais totalement fiable, quelle que soit la configuration du projet.
// Exemple : image lue depuis un stream quelconque
using var stream = await FileSystem.OpenAppPackageFileAsync("mymarker.png");
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
string base64 = Convert.ToBase64String(ms.ToArray());
pin.ImageSource = $"base64-content://{base64}";
Résumé
| Schéma | Usage typique |
|---|---|
https:// | Icône hébergée en ligne |
file:// | Fichier local généré/téléchargé |
embedded:// | Ressource embarquée .NET (EmbeddedResource) |
svg-content:// | SVG généré dynamiquement |
base64-content:// | Image de toute provenance, zéro problème de chemin |
Le nouveau système d’images de Mapsui 5 est beaucoup plus simple à utiliser que l’ancien BitmapRegistry, à condition de comprendre les subtilités liées aux ressources .NET MAUI. Une fois ce point maîtrisé, afficher des icônes personnalisées sur une carte devient véritablement trivial.