Ich zeige eine Wetterkarte in einer GWT-Anwendung. Ich verwende GWT 2.7 und den GWT-Wrapper der GoogleMaps JavaScript API here (gwt-maps-3.8.0-pre1.zip).Refreshing GoogleMaps Kachelserver funktioniert in JavaScript, aber nicht in GWT
Ich verwende einen Kachelserver, um das Wetter abzurufen, das alle 5 Minuten aktualisiert wird. In der 5-Minuten-Marke aktualisiere ich die Karte, indem ich den Zoom auf 1 und dann auf das Original zurückstelle, indem ich eine Größenänderung auslöst und die Wetterebene entferne und dann wieder hinzufüge.
Das hat gut funktioniert. Allerdings habe ich kürzlich festgestellt, dass dies nicht mehr funktioniert: Die Aktualisierung geht nicht einmal auf den Kachelserver, sodass kein neues Wetter angezeigt wird. Wenn Sie meine Karte für 12 Stunden verlassen, werden Sie 12 Stunden altes Wetter sehen. Zuvor wurde die Karte automatisch aktualisiert. Ich habe nichts von meinem Code geändert. Also meine Vermutung ist, dass sich etwas in der zugrunde liegenden GoogleMaps JavaScript API geändert hat.
Allerdings Ich habe dann diese einfache reine JavaScript-Beispiel:
<!DOCTYPE html>
<html>
<head>
<title>Map Test</title>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
#map {
width:90%;
height: 90%;
display:inline-block;
}
</style>
</head>
<body>
<div id="map"></div>
<button type="button" onClick="refreshMap()">Refresh</button>
<script type="text/javascript">
var map;
var tileNEX;
function initMap() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(42.5, -95.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
tileNEX = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD',
isPng: true
});
map.overlayMapTypes.setAt("0",tileNEX);
}
function refreshMap(){
var zoom = map.getZoom();
map.setZoom(1);
map.setZoom(zoom);
//google.maps.event.trigger(map, 'resize');
//var layer = map.overlayMapTypes.getAt(0);
//map.overlayMapTypes.setAt(0, null);
//map.overlayMapTypes.setAt(0, layer);
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
</body>
</html>
Zu meiner Überraschung, das funktioniert noch in Ordnung. Wenn Sie auf die Schaltfläche Aktualisieren klicken, wird die Karte zum Kachelserver geleitet und neue Kacheln abgerufen.
So habe ich versucht, die genau die gleiche Sache in GWT tun:
package com.example.client;
import com.google.gwt.ajaxloader.client.AjaxLoader;
import com.google.gwt.ajaxloader.client.AjaxLoader.AjaxLoaderOptions;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.maps.gwt.client.GoogleMap;
import com.google.maps.gwt.client.LatLng;
import com.google.maps.gwt.client.MapOptions;
import com.google.maps.gwt.client.MapType;
import com.google.maps.gwt.client.MapTypeId;
public class GwtMapTest implements EntryPoint {
@Override
public void onModuleLoad() {
AjaxLoaderOptions options = AjaxLoaderOptions.newInstance();
options.setOtherParms("sensor=false");
Runnable callback = new Runnable() {
public void run() {
createMap();
}
};
AjaxLoader.loadApi("maps", "3", callback, options);
}
public void createMap() {
MapOptions mapOpts = MapOptions.create();
mapOpts.setZoom(4);
mapOpts.setCenter(LatLng.create(37.09024, -95.712891));
mapOpts.setMapTypeId(MapTypeId.TERRAIN);
mapOpts.setStreetViewControl(false);
final GoogleMap map = GoogleMap.create(Document.get().getElementById("map_canvas"), mapOpts);
addWeatherLayer(map);
Button button = new Button("Gwt Refresh");
button.addClickHandler(new ClickHandler(){
@Override
public void onClick(ClickEvent event) {
refreshWeatherLayer(map);
}
});
Button nativeButton = new Button("Native Refresh");
nativeButton.addClickHandler(new ClickHandler(){
@Override
public void onClick(ClickEvent event) {
nativeRefreshWeatherLayer(map);
}
});
RootPanel.get().add(button);
RootPanel.get().add(nativeButton);
}
public native void addWeatherLayer(GoogleMap map) /*-{
var imageMapType = new $wnd.google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/"+ zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new $wnd.google.maps.Size(256, 256),
opacity:.50,
isPng: true
});
map.overlayMapTypes.setAt("0", imageMapType);
}-*/;
private void refreshWeatherLayer(GoogleMap map){
double zoom = map.getZoom();
map.setZoom(1);
map.setZoom(zoom);
MapType layer = map.getOverlayMapTypes().getAt(0);
map.getOverlayMapTypes().setAt(0, null);
map.getOverlayMapTypes().setAt(0, layer);
}
private native void nativeRefreshWeatherLayer(GoogleMap map) /*-{
var zoom = map.getZoom();
map.setZoom(1);
map.setZoom(zoom);
$wnd.google.maps.event.trigger(map, 'resize');
var layer = map.overlayMapTypes.getAt(0);
map.overlayMapTypes.setAt(0, null);
map.overlayMapTypes.setAt(0, layer);
}-*/;
}
Dies sollte das gleiche wie das reine JavaScript Beispiel tun. Wenn ich stattdessen auf die Schaltfläche klicke, wird die Karte aktualisiert (ich sehe, dass die Wetterebene blinkt), , aber sie geht nicht auf den Kachelserver für neue Kacheln.
Weider immer noch funktioniert diese "sorta" im Internet Explorer: vielleicht 1 von 3 mal klicke ich auf die Schaltfläche, die Karte geht tatsächlich auf den Kachelserver. In Chrome geht es jedoch nie auf den Kachelserver, wenn ich auf die Schaltfläche klicke.
Um dies zu ermitteln, schaue ich auf die Registerkarte Netzwerk der Browser-Tools. Ich würde erwarten, dass die Karte den Kachelserver jedes Mal trifft, wenn ich auf die Schaltfläche klicke. Das ist, was es in reinem JavaScript macht, und das war es, was es in GWT getan hat, aber irgendwann in den letzten paar Monaten hat sich das GWT-Verhalten geändert.
Ich glaube nicht, dass dies ein Browser-Caching-Problem ist. Das Problem ist nicht, dass die Karte versucht, neue Fliesen zu holen, aber alte bekommt, ist es, dass es nie versucht, neue Fliesen zu holen. Ich klicke auf die Schaltfläche, und auf der Netzwerkregisterkarte der Entwicklerwerkzeuge passiert nichts.
- Warum sehe ich ein anderes Verhalten in JavaScript vs GWT?
- Warum sehe ich ein anderes Verhalten in verschiedenen Browsern?
- Führt die GWT GoogleMaps-Bibliothek eine Art internes Caching durch? Gibt es eine Möglichkeit, dies zu deaktivieren?
- Warum hat sich dieses Verhalten anscheinend geändert?
- Wie kann ich die GWT-Karte aktualisieren, indem ich für neue Kacheln zum Kachelserver gehe?
Ich habe das Skript in beiden Browsern getestet und es auf GWT versucht. Einer der Unterschiede, die ich fand, ist, dass sie in den Browsern einen Zeitstempel nach der Kachel setzen (/ZOOM/X/Y.png?TIME). Der GWT-Code tut das anscheinend nicht. Im Browser, wenn die Zeit verstrichen ist, ruft IE sie vom Server ab, und Chrome holt sie von localcache. Möglicherweise war die Änderung in dem Kachelserver (oder einem bestimmten Proxy), der die Kachel zwischenspeichert. Können Sie versuchen, die Anfrage im GWT-Code mit einem "? TIME" -Param zu aktualisieren? – fhofmann
@fhofmann Das hat tatsächlich funktioniert, was für mich überraschend ist. Normalerweise fügen Sie einen "Zeit" -Teil hinzu, um den Browser-Cache zu vermeiden, was in diesem Fall nicht das Problem war, da er niemals zum Server gegangen ist und daher niemals den Browser-Cache überprüft hat. Es sieht also so aus, als müsste es ein internes Caching geben, aber nur in der GWT-Version, was für mich keinen Sinn ergibt. Kannst du erklären, warum die GWT- und JS-Versionen anders sind oder warum die "Zeit" in GWT funktioniert? Wenn Sie das als Antwort hinzufügen möchten, würde ich es definitiv zu schätzen wissen. –
Eigentlich habe ich GWT vorher noch nie benutzt. Aber jetzt bin ich neugierig und ich werde versuchen zu finden, wie es funktioniert und wo es Caching sein könnte. – fhofmann