KmlLayer
affiche les éléments KML et GeoRSS dans une superposition de tuiles de l'API Maps JavaScript.
Présentation
L'API Maps JavaScript est compatible avec les formats de données KML et GeoRSS pour afficher des informations géographiques. Ces formats de données sont affichés sur une carte à l'aide d'un objet KmlLayer
, dont le constructeur utilise l'URL d'un fichier KML ou GeoRSS accessible publiquement.
Remarque : la classe KmlLayer
qui génère les superpositions KML dans l'API Maps JavaScript récupère et analyse les fichiers KML pour le rendu via un service hébergé par Google.
Par conséquent, il n'est possible d'afficher les fichiers KML que s'ils sont hébergés sur une URL accessible publiquement sans authentification.
Si vous avez besoin d'accéder à des fichiers privés, d'exercer un contrôle précis sur les caches ou d'envoyer la fenêtre d'affichage du navigateur à un serveur de données géospatiales dans un paramètre de requête, nous vous recommandons d'utiliser des calques de données plutôt que KmlLayer
. Ainsi, les navigateurs de vos utilisateurs demanderont les ressources directement à votre serveur Web.
L'API Maps JavaScript convertit les données XML géographiques fournies en une représentation KML affichée sur la carte au moyen d'une superposition de tuiles de l'API Maps JavaScript. Ce fichier KML ressemble aux éléments de superposition de l'API Maps JavaScript qui vous sont familiers, et fonctionne plus ou moins comme eux. Les éléments KML <Placemark>
et GeoRSS point
sont affichés sous forme de repères. Par exemple, les éléments <LineString>
sont affichés en tant que polylignes et les éléments <Polygon>
en tant que polygones. De même, les éléments <GroundOverlay>
sont affichés sous forme d'images rectangulaires sur la carte. Il est important de noter que ces objets ne sont pas des Markers
, des Polylines
, des Polygons
ni des GroundOverlays
de l'API Maps JavaScript : ils sont affichés dans un seul objet sur la carte.
Les objets KmlLayer
s'affichent sur une carte une fois que leur propriété map
a été définie. Vous pouvez les supprimer de la carte en appelant setMap()
avec null
. L'objet KmlLayer
gère le rendu de ces éléments enfants en récupérant automatiquement les éléments géographiques appropriés selon les limites de la carte. Lorsque les limites sont modifiées, les éléments géographiques de la fenêtre d'affichage ouverte sont rendus automatiquement visibles.
Étant donné que les composants d'un KmlLayer
sont affichés à la demande, le calque vous permet de gérer facilement le rendu de milliers de repères, de polylignes et de polygones. Notez que vous ne pouvez pas accéder directement aux objets de ces composants, bien qu'ils fournissent chacun des événements de clic renvoyant des données sur ces objets individuels.
Options de calque KML
Le constructeur KmlLayer()
transmet facultativement plusieurs KmlLayerOptions
:
map
spécifie leMap
sur lequel afficher leKmlLayer
. Vous pouvez masquer unKmlLayer
en définissant cette valeur surnull
dans la méthodesetMap()
.preserveViewport
indique que la carte ne doit pas être ajustée en fonction des limites du contenu duKmlLayer
lors de l'affichage du calque. Par défaut, lors de l'affichage d'unKmlLayer
, la carte est agrandie et positionnée de manière à afficher l'intégralité du contenu du calque.suppressInfoWindows
indique que les éléments géographiques cliquables dansKmlLayer
ne doivent pas déclencher l'affichage d'objetsInfoWindow
.
En outre, une fois que KmlLayer
est affiché, il contient une propriété metadata
immuable contenant le nom, la description, l'extrait et l'auteur du calque dans un littéral d'objet KmlLayerMetadata
. Vous pouvez inspecter ces informations à l'aide de la méthode getMetadata()
. Étant donné que l'affichage des objets KmlLayer
nécessite une communication asynchrone avec un serveur externe, vous devez écouter l'événement metadata_changed
, qui indique que la propriété a été renseignée.
L'exemple suivant construit un KmlLayer
à partir du flux GeoRSS donné :
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: 49.496675, lng: -102.65625 }, } ); const georssLayer = new google.maps.KmlLayer({ url: "http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss", }); georssLayer.setMap(map); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: 49.496675, lng: -102.65625 }, }); const georssLayer = new google.maps.KmlLayer({ url: "http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss", }); georssLayer.setMap(map); } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>GeoRSS Layers</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- The `defer` attribute causes the script to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
Essayer avec un exemple
L'exemple suivant construit un KmlLayer
à partir du flux KML donné :
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 11, center: { lat: 41.876, lng: -87.624 }, } ); const ctaLayer = new google.maps.KmlLayer({ url: "https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml", map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 11, center: { lat: 41.876, lng: -87.624 }, }); const ctaLayer = new google.maps.KmlLayer({ url: "https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml", map: map, }); } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>KML Layers</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- The `defer` attribute causes the script to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
Essayer avec un exemple
Informations sur les éléments géographiques KML
Étant donné que le fichier KML peut inclure un grand nombre d'éléments géographiques, vous ne pouvez pas accéder à ces données directement à partir de l'objet KmlLayer
. À la place, les éléments géographiques s'affichent de manière à ressembler à des superpositions d'API Maps JavaScript cliquables.
Lorsque vous cliquez sur l'un d'eux, un InfoWindow
contenant les informations KML <title>
et <description>
de l'élément géographique apparaît par défaut.
En outre, un clic sur un élément géographique KML génère un KmlMouseEvent
, qui transmet les informations suivantes :
position
indique les coordonnées de latitude/longitude auxquelles l'InfoWindow
doit être ancrée pour cet élément géographique KML. Cette position correspond généralement à l'emplacement du clic pour les polygones, les polylignes et les GroundOverlays, mais à l'origine réelle pour les repères.pixelOffset
indique le décalage par rapport à laposition
ci-dessus pour ancrer la "queue" duInfoWindow
. Pour les objets polygonaux, ce décalage est généralement de0,0
, mais pour un repère, il est ajusté par rapport à sa hauteur.featureData
contient une structure JSON deKmlFeatureData
.
Vous trouverez ci-dessous un exemple d'objet KmlFeatureData
:
{ author: { email: "nobody@google.com", name: "Mr Nobody", uri: "http://example.com" }, description: "description", id: "id", infoWindowHtml: "html", name: "name", snippet: "snippet" }
L'exemple suivant affiche le texte <Description>
de l'élément géographique KML dans un <div>
latéral lorsque l'utilisateur clique sur l'élément :
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: { lat: 37.06, lng: -95.68 }, } ); const kmlLayer = new google.maps.KmlLayer({ url: "https://raw.githubusercontent.com/googlearchive/kml-samples/gh-pages/kml/Placemark/placemark.kml", suppressInfoWindows: true, map: map, }); kmlLayer.addListener("click", (kmlEvent) => { const text = kmlEvent.featureData.description; showInContentWindow(text); }); function showInContentWindow(text: string) { const sidebar = document.getElementById("sidebar") as HTMLElement; sidebar.innerHTML = text; } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: { lat: 37.06, lng: -95.68 }, }); const kmlLayer = new google.maps.KmlLayer({ url: "https://raw.githubusercontent.com/googlearchive/kml-samples/gh-pages/kml/Placemark/placemark.kml", suppressInfoWindows: true, map: map, }); kmlLayer.addListener("click", (kmlEvent) => { const text = kmlEvent.featureData.description; showInContentWindow(text); }); function showInContentWindow(text) { const sidebar = document.getElementById("sidebar"); sidebar.innerHTML = text; } } window.initMap = initMap;
CSS
/* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #container { height: 100%; display: flex; } #sidebar { flex-basis: 15rem; flex-grow: 1; padding: 1rem; max-width: 30rem; height: 100%; box-sizing: border-box; overflow: auto; } #map { flex-basis: 0; flex-grow: 4; height: 100%; }
HTML
<html> <head> <title>KML Feature Details</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="container"> <div id="map"></div> <div id="sidebar"></div> </div> <!-- The `defer` attribute causes the script to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
Essayer avec un exemple
Restrictions de taille et de complexité pour le rendu KLM
L'API Maps JavaScript limite la taille et la complexité des fichiers KML chargés. Voici un récapitulatif des limites actuelles.
Remarque : Ces limites peuvent être modifiées à tout moment.
- Taille maximale du fichier récupéré (KML brut, GeoRSS brut ou KMZ compressé)
- 3 Mo
- Taille maximale du fichier KML décompressé
- 10 Mo
- Taille maximale des fichiers image non compressés dans les fichiers KMZ
- 500 Ko par fichier
- Nombre maximal de liens réseau
- 10
- Nombre maximal d'éléments géographiques dans tout le document
- 1 000
- Nombre de calques KML
- Le nombre de calques KML qu'il est possible d'afficher sur une seule carte Google Maps est limité. Si vous dépassez cette limite, aucun de vos calques n'apparaîtra sur la carte et une erreur sera signalée dans la console JavaScript de votre navigateur Web. Cette limite est basée sur la combinaison entre le nombre de classes
KmlLayer
créées et la longueur totale de toutes les URL utilisées pour créer ces calques. Chaque nouveauKmlLayer
que vous créez occupe une partie des limites du calque, plus une autre partie basée sur la longueur de l'URL à partir de laquelle le fichier KML a été chargé. Le nombre de calques que vous pouvez ajouter dépend donc de l'application. Il est en général possible de charger entre 10 et 20 calques sans atteindre cette limite. Si vous atteignez quand même la limite, utilisez un réducteur d'URL pour réduire les URL des fichiers KML. Vous pouvez également créer un seul fichier KML composé de NetworkLinks vers chacune des URL KML.
Considérations sur les performances et la mise en cache
Les serveurs de Google mettront temporairement en cache les fichiers KML pour réduire la charge sur vos serveurs. Cela améliorera également les performances pour vos utilisateurs lors des clics, des panoramiques ou des zooms sur la carte, car les segments appropriés de votre fichier KML seront représentés de manière optimale compte tenu de l'espace.
Voici nos recommandations pour accroître les performances :
- Utilisez un tag
<expires>
approprié dans le code KML.
KmlLayer
n'utilisera pas d'en-têtes HTTP pour décider comment mettre en cache les fichiers KML. - Ne générez pas les fichiers de manière dynamique au moment de la requête.
Générez-les plutôt avant qu'ils ne soient nécessaires et livrez-les en mode statique. Si votre serveur met beaucoup de temps à transmettre le fichier KML, leKmlLayer
peut ne pas s'afficher. - N'essayez pas de contourner les caches, sauf si vous savez que votre fichier a réellement été mis à jour.
Si vous contournez les caches systématiquement (par exemple, en ajoutant un nombre aléatoire ou l'heure de l'utilisateur en tant que paramètre de requête), vous pouvez facilement surcharger votre serveur si votre site devient soudainement populaire et que vous livrez des fichiers KML volumineux.
Le cache peut également livrer des données obsolètes aux utilisateurs si l'horloge de l'utilisateur est incorrecte et si le tag<expires>
n'a pas été correctement défini.
Publiez plutôt des fichiers statiques mis à jour avec un nouveau numéro de révision distinct et utilisez du code côté serveur pour mettre à jour de façon dynamique l'URL transmise àKmlLayer
avec la version actuelle. - Limitez les modifications de vos fichiers KML à une fois par minute.
Si la taille de tous les fichiers dépasse 1 Mo (sans compression), limitez les modifications à une fois toutes les cinq minutes. - Lorsque vous utilisez un serveur de données géospatiales, évitez d'utiliser des paramètres de requête pour limiter la fenêtre d'affichage des calques.
À la place, vous pouvez limiter la fenêtre d'affichage de la carte avec l'événementbounds_changed
. Seuls des éléments géographiques pouvant être affichés automatiquement seront envoyés aux utilisateurs.
Si votre serveur de données géospatiales contient une grande quantité de données, envisagez plutôt d'utiliser des calques de données. - Lorsque vous utilisez un serveur de données géospatiales, utilisez plusieurs
KmlLayer
(au lieu d'un seulKmlLayer
avec des paramètres de requête différents) pour chaque groupe d'éléments géographiques que vous souhaitez que les utilisateurs puissent activer/désactiver. - Utilisez des fichiers KMZ compressés pour réduire la taille des fichiers.
- Si vous utilisez Google Cloud Storage ou une autre solution de stockage cloud, évitez les fonctionnalités telles que les URL signées ou les jetons temporaires pour appliquer le contrôle des accès. Vous pourriez empêcher involontairement la mise en cache.
- Réduisez la précision de tous les points à un niveau approprié.
- Fusionnez et simplifiez la géométrie des éléments géographiques similaires tels que des polygones et des polylignes.
- Supprimez tous les éléments ou les ressources d'image inutilisés.
- Supprimez tous les éléments non compatibles.
Si vous devez accéder à des données privées, empêcher la mise en cache ou envoyer la fenêtre d'affichage du navigateur à un serveur de données géospatiales en tant que paramètre de requête, nous vous recommandons d'utiliser des couches de données plutôt que KmlLayer
. Ainsi, les navigateurs de vos utilisateurs demanderont les ressources directement à votre serveur Web.
Éléments KML pris en charge
L'API Maps JavaScript est compatible avec les éléments KML suivants. En général, l'analyseur KML ignore silencieusement les tags XML qu'il ne comprend pas.
- Repères
- Icônes
- Dossiers
- Code HTML descriptif : remplacement d'entité via <BalloonStyle> et <text>
- KMZ (fichier KML compressé, y compris les images jointes)
- Polylignes et polygones
- Styles des polylignes et des polygones, y compris la couleur, le remplissage et l'opacité
- Liens réseau pour importer les données de façon dynamique
- Superpositions au sol et superpositions d'écran
Le tableau suivant fournit les détails complets des éléments KML pris en charge.
Élément KML | Pris en charge dans l'API ? | Commentaire |
---|---|---|
<address> | non | |
<AddressDetails> | non | |
<Alias> | N/A | <Model> non pris en charge |
<altitude> | non | |
<altitudeMode> | non | |
<atom:author> | oui | |
<atom:link> | oui | |
<atom:name> | oui | |
<BalloonStyle> | partiellement | seul <text> pris en charge |
<begin> | N/A | <TimeSpan> non pris en charge |
<bgColor> | non | |
<bottomFov> | N/A | <PhotoOverlay> non pris en charge |
<Camera> | non | |
<Change> | partiellement | seuls les changements de style sont pris en charge |
<color> | partiellement | inclut #AABBGGRR et #BBGGRR ; non pris en charge dans <IconStyle>, <ScreenOverlay> et <GroundOverlay> |
<colorMode> | non | |
<cookie> | non | |
<coordinates> | oui | |
<Create> | non | |
<Data> | oui | |
<Delete> | non | |
<description> | oui | Le contenu HTML est autorisé, mais il est épuré pour éviter les attaques entre navigateurs. Les remplacements d'entités au format $[dataName] ne sont pas pris en charge. |
<displayMode> | non | |
<DisplayName> | non | |
<Document> | partiellement | implicitement, les enfants sont pris en charge ; sans effet en tant qu'enfant d'autres éléments géographiques |
<drawOrder> | non | |
<east> | oui | |
<end> | N/A | <TimeSpan> non pris en charge |
<expires> | oui | voir la section Résumé pour plus de détails |
<ExtendedData> | partiellement | <Data> non typé uniquement, aucun remplacement d'entité <SimpleData> ou <Schema>, au format $[dataName] n'est pris en charge.
|
<extrude> | non | |
<fill> | oui | |
<flyToView> | non | |
<Folder> | oui | |
<geomColor> | non | obsolète |
<GeometryCollection> | non | obsolète |
<geomScale> | non | obsolète |
<gridOrigin> | N/A | <PhotoOverlay> non pris en charge |
<GroundOverlay> | oui | ne peut pas pivoter |
<h> | oui | obsolète |
<heading> | oui | |
hint | oui | target=... pris en charge |
<hotSpot> | oui | |
<href> | oui | |
<httpQuery> | non | |
<Icon> | oui | ne peut pas pivoter |
<IconStyle> | oui | |
<ImagePyramid> | N/A | <PhotoOverlay> non pris en charge |
<innerBoundaryIs> | oui | implicitement selon l'ordre <LinearRing> |
<ItemIcon> | N/A | <ListStyle> non pris en charge |
<key> | N/A | <StyleMap> non pris en charge |
<kml> | oui | |
<labelColor> | non | obsolète |
<LabelStyle> | non | |
<latitude> | oui | |
<LatLonAltBox> | oui | |
<LatLonBox> | oui | |
<leftFov> | N/A | <PhotoOverlay> non pris en charge |
<LinearRing> | oui | |
<LineString> | oui | |
<LineStyle> | oui | |
<Link> | oui | |
<linkDescription> | non | |
<linkName> | non | |
<linkSnippet> | non | |
<listItemType> | N/A | <ListStyle> non pris en charge |
<ListStyle> | non | |
<Location> | N/A | <Model> non pris en charge |
<Lod> | oui | |
<longitude> | oui | |
<LookAt> | non | |
<maxAltitude> | oui | |
<maxFadeExtent> | oui | |
<maxHeight> | N/A | <PhotoOverlay> non pris en charge |
<maxLodPixels> | oui | |
<maxSessionLength> | non | |
<maxWidth> | N/A | <PhotoOverlay> non pris en charge |
<message> | non | |
<Metadata> | non | obsolète |
<minAltitude> | oui | |
<minFadeExtent> | oui | |
<minLodPixels> | oui | |
<minRefreshPeriod> | non | <NetworkLink> |
<Model> | non | |
<MultiGeometry> | partiellement | affiché, mais en tant qu'éléments géographiques séparés dans le panneau de gauche |
<name> | oui | |
<near> | N/A | <PhotoOverlay> non pris en charge |
<NetworkLink> | oui | |
<NetworkLinkControl> | partiellement | <Update> et <expires> partiellement pris en charge. L'API ignore les paramètres d'expiration dans les en-têtes HTTP, mais utilise ceux qui sont spécifiés dans le KML. En l'absence de paramètres d'expiration, ou durant l'intervalle de validité, Google Maps peut mettre cache les données récupérées sur Internet pour une durée non spécifiée. Il est possible de forcer une nouvelle récupération des données depuis Internet en renommant le document et en allant le chercher à une autre URL, ou en s'assurant que le document contient des paramètres d'expiration appropriés. |
<north> | oui | |
<open> | oui | |
<Orientation> | N/A | <Model> non pris en charge |
<outerBoundaryIs> | oui | implicitement selon l'ordre <LinearRing> |
<outline> | oui | |
<overlayXY> | non | |
<Pair> | N/A | <StyleMap> non pris en charge |
<phoneNumber> | non | |
<PhotoOverlay> | non | |
<Placemark> | oui | |
<Point> | oui | |
<Polygon> | oui | |
<PolyStyle> | oui | |
<range> | oui | |
<refreshInterval> | partiellement | <Link> uniquement ; pas dans <Icon> |
<refreshMode> | oui | En-têtes HTTP non pris en charge pour le mode "onExpire". Voir les remarques sur <Update> et <expires> plus haut. |
<refreshVisibility> | non | |
<Region> | oui | |
<ResourceMap> | N/A | <Model> non pris en charge |
<rightFov> | N/A | <PhotoOverlay> non pris en charge |
<roll> | N/A | <Camera> et <Model> non pris en charge |
<rotation> | non | |
<rotationXY> | non | |
<Scale> | N/A | <Model> non pris en charge |
<scale> | non | |
<Schema> | non | |
<SchemaData> | non | |
<ScreenOverlay> | oui | ne peut pas pivoter |
<screenXY> | non | |
<shape> | N/A | <PhotoOverlay> non pris en charge |
<SimpleData> | N/A | <SchemaData> non pris en charge |
<SimpleField> | N/A | <Schema> non pris en charge |
<size> | oui | |
<Snippet> | oui | |
<south> | oui | |
<state> | N/A | <ListStyle> non pris en charge |
<Style> | oui | |
<StyleMap> | non | effets de survol (surbrillance) non pris en charge |
<styleUrl> | N/A | <StyleMap> non pris en charge |
<targetHref> | partiellement | pris en charge dans <Update>, pas dans <Alias> |
<tessellate> | non | |
<text> | oui | le remplacement de $[geDirections] n'est pas pris en charge |
<textColor> | non | |
<tileSize> | N/A | <PhotoOverlay> non pris en charge |
<tilt> | non | |
<TimeSpan> | non | |
<TimeStamp> | non | |
<topFov> | N/A | <PhotoOverlay> non pris en charge |
<Update> | partiellement | uniquement les changements de style, pas <Create> ou <Delete> |
<Url> | oui | obsolète |
<value> | oui | |
<viewBoundScale> | non | |
<viewFormat> | non | |
<viewRefreshMode> | partiellement | "onStop" est pris en charge |
<viewRefreshTime> | oui | |
<ViewVolume> | N/A | <PhotoOverlay> non pris en charge |
<visibility> | partiellement | oui sur <Folder> ; les repères enfants héritent de leur visibilité |
<w> | oui | obsolète |
<west> | oui | |
<when> | N/A | <TimeStamp> non pris en charge |
<width> | oui | |
<x> | oui | obsolète |
<y> | oui | obsolète |