J'ai eu du mal à mettre à jour l'API Google Maps v3 correctement. J'ai un minuteur javascript en cours d'exécution qui devrait rafraîchir périodiquement la couche de trafic mais je ne le vois pas se produire.
Si je comprends bien la documentation, je devrais être capable de dire quelque chose comme "layer.setMap (null);" suivi de "layer.setMap (map);" pour actualiser la couche (source: https://developers.google.com/maps/documentation/javascript/reference#TrafficLayer ).
Je sais que les nouvelles tuiles de carte sont en cours de téléchargement (par exemple, je peux les voir dans la section Ressources des outils de développement de Chrome), mais le navigateur ne les affiche pas. Il manque probablement quelque chose de fondamental.
J'ai essayé plusieurs choses, notamment:
Existe-t-il un moyen de garantir que le navigateur restituera les nouvelles images sans forcer le rechargement d'une page complète?
Ci-dessous est une version simplifiée de la page (basée sur la réponse de Google Maps actualiser la couche de trafic ).
<html>
<head>
<title>Map Testing</title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=weather"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
var map,
trafficLayer,
mapTimerHandle;
$(function() {
initMap();
mapTimerHandle = setInterval(refreshMap, 15000);
});
function refreshMap() {
trafficLayer.setMap(null);
trafficLayer.setMap(map);
}
function initMap() {
var mapDiv = document.getElementById('map');
map = new google.maps.Map(mapDiv, {zoom: 15, center: new google.maps.LatLng(40.7127, -74.0059)});
trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
</script>
</head>
<body style="margin:0px;">
<div id="map" style="width:100%; height:100%;"></div>
</body>
</html>
Ok, ce que j'ai trouvé, et ce qui est mentionné ci-dessus, c'est que trafficLayer.setMap(null)
et trafficLayer.setMap(map)
- juste commutateurs tuiles avec trafic dessiné vers tuiles sans trafic . De plus, map.setZoom(map.getZoom())
(et toutes les autres variantes de zoom) ne fonctionne pas car les tuiles sont déjà dans le cache et les scripts google n'essaient même pas de télécharger de nouvelles depuis le serveur.
En outre, il semble que si vous ouvrez simplement Google Maps et activez la couche de trafic, ce n'est pas rafraîchissant! Un tel boiteux, google!
Nous devons donc trouver un moyen différent de le résoudre.
La première pensée est d'utiliser window.location.reload(true)
qui videra le cache d'image - et nous voyons que cela fonctionne. Cependant, ce n'est pas une bonne façon de procéder - le rechargement de la page entière prend trop de temps. Que diriez-vous de recharger des images? Essayons!
function reloadTiles() {
var tiles = $("#map-canvas").find("img");
for (var i = 0; i < tiles.length; i++) {
var src = $(tiles[i]).attr("src");
if (/googleapis.com\/vt\?pb=/.test(src)) {
var new_src = src.split("&ts")[0] + '&ts=' + (new Date()).getTime();
$(tiles[i]).attr("src", new_src);
}
}
}
Et nous appelons cette fonction toutes les N secondes: setInterval(reloadTiles, 5000)
certains commentaires:
$("#map-canvas").find("img")
- récupérera toutes les images de votre conteneur de carte (map-canvas
dans mon cas). Tous ne sont pas des tuiles, nous devons donc les filtrer - j'ai remarqué que les tuiles sont chargées à partir de domaines comme mts(digit).googleapis.com/vt?pb=(hella long param)
. D'autres images de carte sont chargées à partir de maps.gstatic.com
.
Nous obtenons donc des images de tuiles, ajoutons de faux paramètres et modifions leur src. Bénéfice!
Btw, j'ai trouvé que le trafic vraiment change en réel temps - les tuiles peuvent être différentes chaque seconde.
Modifier
Oh, désolé, voici échantillon de travail. Et c'est un Moscou enneigé avec un trafic énorme :)
Je n'ai pas encore travaillé avec les couches de trafic, donc je ne sais pas si cela fonctionnera pour vous. J'ai lu l'astuce setZoom (getZoom ()) mais quand j'ai besoin de rafraîchir les tuiles (la classique. La carte elle-même) ça n'a pas marché non plus. J'ai besoin d'afficher/masquer une grille dans Gmaps (sans recharger la page)
Après avoir cherché et testé, je l'ai fait fonctionner avec ces trois lignes:
google.maps.event.trigger(map, 'resize'); // Can't remember if really helps
map.setZoom( map.getZoom() -1 );
map.setZoom( map.getZoom() +1 ); // It won't flicker or make the transition between zoom levels. GMap just ignore the zoom change but redraw the tiles :/
Je répète. Je ne sais pas si cela fonctionne avec les couches de trafic, mais testez-le quand même. Cela m'a gardé éveillé 2 jours.
Google documentation dit:
L'API Google Maps vous permet d'ajouter des informations sur le trafic en temps réel (lorsque cela est pris en charge) à vos cartes à l'aide de l'objet TrafficLayer. Des informations sur le trafic sont fournies pour l'heure à laquelle la demande est effectuée .
Je crois que votre fonction refreshMap()
ne fera que masquer et afficher la couche de trafic (via la méthode .setMap()
) et ne récupérera pas réellement les données de trafic mises à jour (le cas échéant).
Le seul moyen efficace serait donc de renouveler votre requête en réinitialisant l'objet TrafficLayer()
.
EDIT: J'ai surveillé le trafic réseau et je n'ai vu aucune nouvelle demande. La vue doit être modifiée pour forcer la récupération de nouvelles données (par exemple en redéfinissant le zoom) ...
function refreshMap() {
trafficLayer.setMap(null);
trafficLayer = null;
map.setZoom(map.getZoom()); // this renews the view and forces new data to be requested
setTimeout(function () {
trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}, 100);
}
Ainsi, avec la méthode mise à jour ci-dessus, le fichier JS ci-dessous est récupéré à partir de https://maps.googleapis.com/maps/api/js/
:
ViewportInfoService.GetViewportInfo?1m6&1m2&1d40.67711350268867&2d-74.09477919619036&2m2&1d40.747903965754034&2d-73.91666125686464&2u15&4sen-US&5e0&6sm%40285000000&7b0&8e0&9b0&callback=_xdc_._e0qzs3&token=110512
qui contient des données de trafic telles que:
...,["traffic",[[40.74725696280421,-74.102783203125],[40.75557964275589,-73.916015625]]]...
J'utilise beaucoup la couche de trafic. J'ai ajouté un bouton pour basculer le calque mais j'ai trouvé que pour le cacher, j'ai dû définir le calque lui-même comme nul.
Mon code pour afficher la couche:
if (MapManager.trafficLayer == null)
{
MapManager.trafficLayer = new google.maps.TrafficLayer();
}
MapManager.trafficLayer.setMap(MapManager.map);
Ensuite, pour masquer à nouveau le calque:
MapManager.trafficLayer.setMap(null);
MapManager.trafficLayer = null;
Idéalement, ce que vous avez suggéré ci-dessus serait mieux, mais pour moi, cela semble fonctionner très bien.
La façon dont vous actualisez le calque fonctionne correctement.
Voici votre code édité pour le prouver:
<html>
<head>
<title>Map Testing</title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api /js?v=3.exp&libraries=weather"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
var map, trafficLayer;
var vis = false;
$(function ()
{
initMap();
});
function refreshMap()
{
if (vis)
{
trafficLayer.setMap(null)
vis = false;
}
else
{
trafficLayer.setMap(map);
vis = true;
}
}
function initMap()
{
var mapDiv = document.getElementById('map');
map = new google.maps.Map(mapDiv, {zoom: 15, center: new google.maps.LatLng(40.7127, -74.0059)});
trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
vis = true;
setInterval(function ()
{
refreshMap();
}, 3000);
}
</script>
</head>
<body style="margin:0px;">
<div id="map" style="width:100%; height:100%;"></div>
</body>
J'ai ajouté une propriété de visibilité pour basculer le calque toutes les 2 secondes. Vous remarquerez comment il s'allume et s'éteint. Parce que comme vous l'appeliez, je pense qu'il n'a pas eu assez de temps pour se rafraîchir.
J'ai également ajouté l'intervalle dans la fonction initMap après la première définition de la carte de la couche.
J'espère que cela pourra aider.
ÉDITER. Juste pour ajouter à cela, où le trafic est en temps réel où il est pris en charge, dans certains cas, il est basé sur des données historiques et ne se rafraîchira pas sur une courte période. Mais les données de trafic sont récupérées au moment de chaque demande comme spécifié dans les documents: https://developers.google.com/maps/documentation/javascript/trafficlayer#traffic_layer
essayez cet extrait de code, cela peut vous aider
function init() {
var map,
trafficLayer,
mapTimerHandle;
var mapDiv = document.getElementById('map');
map = new google.maps.Map(mapDiv, {
zoom: 14,
center: new google.maps.LatLng(40.7127, -74.0059)
});
trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
$(document).ready(function () {
init();
setInterval(function () {
google.maps.event.trigger(map, 'resize');
map.fitBounds();
}, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
<div id="map" style="width:600px; height:450px"></div>
La réponse de Sergio est toujours la bonne, mais je pense que Google a mis à jour son API et ses URL (un risque mentionné par un commentateur).
Le test correct serait maintenant:
....
if (/googleapis.com\/maps\/vt\?pb=/.test(src)) {
...
Cela pourrait fonctionner pour vous.
constructor(){
this.mapOptions = {
zoom: 11,
mapTypeId: google.maps.MapTypeId.HYBRID,
mapTypeControl: false,
streetViewControl: false,
fullscreenControl: false
}
this.map = new google.maps.Map(
this.mapElement.nativeElement,
this.mapOptions
);
this.map.setCenter(this.latLng);
this.map.setZoom(7);
this.trafficLayer = new google.maps.TrafficLayer();
// console.log(trafficLayer);
this.trafficLayer.setMap(this.map);
}
J'ai ajouté la couche de trafic sur la carte au départ, en utilisant le code ci-dessous pour basculer le trafic en fonction des besoins de l'utilisateur
// use this method to toggle traffic layer on the map.
trafficLayerOnMap() {
if (this.isTrafficEnabled) {
this.trafficLayer.setMap(null);
this.isTrafficEnabled = false;
} else {
this.trafficLayer = new google.maps.TrafficLayer();
this.trafficLayer.setMap(this.map);
this.isTrafficEnabled = true;
}
}