ingo@796: package de.intevation.flys.client.client.ui.map; ingo@796: ingo@825: import java.util.List; ingo@825: ingo@823: import com.google.gwt.core.client.GWT; ingo@825: import com.google.gwt.user.client.rpc.AsyncCallback; ingo@797: import com.google.gwt.user.client.ui.HorizontalPanel; ingo@797: import com.google.gwt.user.client.ui.Widget; ingo@797: ingo@796: import com.smartgwt.client.widgets.Canvas; ingo@798: import com.smartgwt.client.widgets.events.ResizedEvent; ingo@798: import com.smartgwt.client.widgets.events.ResizedHandler; ingo@796: import com.smartgwt.client.widgets.layout.HLayout; ingo@798: import com.smartgwt.client.widgets.layout.VLayout; ingo@796: ingo@797: import org.gwtopenmaps.openlayers.client.Bounds; ingo@806: import org.gwtopenmaps.openlayers.client.Map; ingo@825: import org.gwtopenmaps.openlayers.client.event.VectorFeatureAddedListener; ingo@825: import org.gwtopenmaps.openlayers.client.event.VectorFeatureAddedListener.FeatureAddedEvent; ingo@825: import org.gwtopenmaps.openlayers.client.event.VectorFeatureRemovedListener; ingo@825: import org.gwtopenmaps.openlayers.client.event.VectorFeatureRemovedListener.FeatureRemovedEvent; ingo@825: import org.gwtopenmaps.openlayers.client.feature.VectorFeature; ingo@825: import org.gwtopenmaps.openlayers.client.format.GeoJSON; ingo@806: import org.gwtopenmaps.openlayers.client.layer.Layer; ingo@825: import org.gwtopenmaps.openlayers.client.layer.Vector; ingo@797: import org.gwtopenmaps.openlayers.client.layer.WMS; ingo@797: import org.gwtopenmaps.openlayers.client.layer.WMSParams; ingo@823: import org.gwtopenmaps.openlayers.client.layer.WMSOptions; ingo@797: ingo@825: import de.intevation.flys.client.shared.model.Artifact; ingo@825: import de.intevation.flys.client.shared.model.ArtifactDescription; ingo@806: import de.intevation.flys.client.shared.model.AttributedTheme; ingo@796: import de.intevation.flys.client.shared.model.Collection; ingo@825: import de.intevation.flys.client.shared.model.Data; ingo@825: import de.intevation.flys.client.shared.model.DataItem; ingo@825: import de.intevation.flys.client.shared.model.DataList; ingo@825: import de.intevation.flys.client.shared.model.DefaultData; ingo@825: import de.intevation.flys.client.shared.model.DefaultDataItem; ingo@1376: import de.intevation.flys.client.shared.model.MapConfig; ingo@806: import de.intevation.flys.client.shared.model.Theme; ingo@806: import de.intevation.flys.client.shared.model.ThemeList; ingo@796: import de.intevation.flys.client.shared.model.OutputMode; ingo@796: ingo@825: import de.intevation.flys.client.client.Config; ingo@825: import de.intevation.flys.client.client.services.StepForwardService; ingo@825: import de.intevation.flys.client.client.services.StepForwardServiceAsync; ingo@1365: import de.intevation.flys.client.client.services.MapOutputService; ingo@1365: import de.intevation.flys.client.client.services.MapOutputServiceAsync; ingo@1364: import de.intevation.flys.client.client.event.RedrawRequestHandler; ingo@1364: import de.intevation.flys.client.client.event.RedrawRequestEvent; ingo@796: import de.intevation.flys.client.client.ui.CollectionView; ingo@796: import de.intevation.flys.client.client.ui.OutputTab; ingo@806: import de.intevation.flys.client.client.ui.ThemePanel; ingo@796: ingo@796: ingo@1364: public class MapOutputTab extends OutputTab implements RedrawRequestHandler { ingo@796: ingo@823: public static final String DEFAULT_SRID = "4326"; ingo@823: ingo@825: public static final String BARRIERS_PARAMETER_KEY = "uesk.barriers"; ingo@825: ingo@1269: public static final String WSPLGEN_FACET = "floodmap.wsplgen"; ingo@1269: ingo@825: ingo@825: protected StepForwardServiceAsync feedService = ingo@825: GWT.create(StepForwardService.class); ingo@823: ingo@1365: protected MapOutputServiceAsync mapService = ingo@1365: GWT.create(MapOutputService.class); ingo@1365: ingo@825: protected MapToolbar controlPanel; ingo@806: protected ThemePanel themePanel; ingo@806: protected Widget mapPanel; ingo@797: ingo@797: protected FloodMap floodMap; ingo@796: ingo@796: ingo@796: public MapOutputTab( ingo@796: String title, ingo@796: Collection collection, ingo@796: OutputMode mode, ingo@796: CollectionView collectionView ingo@796: ){ ingo@1364: super(title, collection, collectionView, mode); ingo@796: ingo@1376: mapService.doOut(collection, new AsyncCallback() { ingo@1365: public void onFailure(Throwable caught) { ingo@1365: GWT.log("MAP ERROR: " + caught.getMessage()); ingo@1365: } ingo@1365: ingo@1376: public void onSuccess(MapConfig c) { ingo@1365: GWT.log("MAP SUCCESS!"); ingo@1376: ingo@1376: Bounds max = boundsFromString(c.getMaxExtent()); ingo@1376: Bounds initial = boundsFromString(c.getInitialExtent()); ingo@1376: ingo@1376: if (initial == null) { ingo@1376: GWT.log("Warning: No initial extent set."); ingo@1376: initial = max; ingo@1376: } ingo@1376: ingo@1376: setFloodmap(new FloodMap(c.getSrid(), max)); ingo@1376: ingo@1376: initLayout(); ingo@1376: initBarriers(); ingo@1376: ingo@1376: GWT.log("MAX EXTENT: " + max); ingo@1376: GWT.log("ZOOM TO: " + initial); ingo@1376: getMap().zoomToExtent(initial); ingo@1365: } ingo@1365: } ingo@1365: ); ingo@796: } ingo@796: ingo@796: ingo@796: protected void initLayout() { ingo@798: VLayout rootLayout = new VLayout(); ingo@798: rootLayout.setHeight100(); ingo@798: rootLayout.setWidth100(); ingo@798: rootLayout.setMembersMargin(2); ingo@797: raimund@1386: final HLayout hlayout = new HLayout(); raimund@1386: hlayout.setHeight("*"); raimund@1386: hlayout.setWidth100(); raimund@1386: hlayout.setMembersMargin(2); ingo@798: raimund@1386: final Canvas themePanelWrapper = createThemePanel(); raimund@1386: raimund@1386: controlPanel = createControlPanel(); ingo@800: mapPanel = floodMap.getMapWidget(); ingo@797: final HorizontalPanel layout = new HorizontalPanel(); ingo@798: layout.setWidth("99%"); ingo@798: layout.setHeight("99%"); ingo@797: layout.add(mapPanel); ingo@797: ingo@806: hlayout.addMember(themePanelWrapper); raimund@1386: hlayout.addMember(layout); ingo@798: ingo@798: rootLayout.addMember(controlPanel); ingo@798: rootLayout.addMember(hlayout); ingo@798: raimund@1386: hlayout.addResizedHandler(new ResizedHandler() { ingo@798: public void onResized(ResizedEvent e) { raimund@1386: Integer height = hlayout.getHeight(); raimund@1386: Integer width = hlayout.getWidth() - themePanelWrapper.getWidth(); ingo@798: ingo@798: height = height * 99 / 100; ingo@798: width = width * 99 / 100; ingo@798: ingo@798: String w = String.valueOf(width) + "px"; ingo@798: String h = String.valueOf(height) + "px"; ingo@798: ingo@798: floodMap.setSize(w, h); ingo@798: } ingo@798: }); ingo@798: ingo@798: setPane(rootLayout); ingo@797: } ingo@797: ingo@797: ingo@825: protected void initBarriers() { ingo@825: Vector vector = floodMap.getBarrierLayer(); ingo@825: vector.addVectorFeatureAddedListener( ingo@825: new VectorFeatureAddedListener() { ingo@825: public void onFeatureAdded(FeatureAddedEvent e) { ingo@825: saveBarriers(); ingo@825: } ingo@825: } ingo@825: ); ingo@825: ingo@825: vector.addVectorFeatureRemovedListener( ingo@825: new VectorFeatureRemovedListener() { ingo@825: public void onFeatureRemoved(FeatureRemovedEvent e) { ingo@825: saveBarriers(); ingo@825: } ingo@825: } ingo@825: ); ingo@825: ingo@825: ingo@825: Artifact artifact = getArtifact(); ingo@825: ingo@825: if (artifact == null) { ingo@825: return; ingo@825: } ingo@825: ingo@825: ArtifactDescription desc = artifact.getArtifactDescription(); ingo@825: ingo@825: String geojson = getGeoJSONFromStatic(desc); ingo@825: geojson = geojson != null ? geojson : getGeoJSONFromDynamic(desc); ingo@825: ingo@825: if (geojson == null || geojson.length() == 0) { ingo@825: GWT.log("No geojson string found -> no barriers existing."); ingo@825: return; ingo@825: } ingo@825: ingo@825: GeoJSON reader = new GeoJSON(); ingo@825: VectorFeature[] features = reader.read(geojson); ingo@825: ingo@825: vector.addFeatures(features); ingo@825: } ingo@825: ingo@825: ingo@1382: public void addLayer(Layer layer) { ingo@1382: Map map = getMap(); ingo@1382: ingo@1382: if (map != null) { ingo@1382: GWT.log("Add new layer '" + layer.getName() + "' to map."); ingo@1382: map.addLayer(layer); ingo@1382: } ingo@1382: } ingo@1382: ingo@1382: ingo@1382: public void removeLayer(String name) { ingo@1382: Map map = getMap(); ingo@1382: ingo@1382: Layer[] layers = map.getLayers(); ingo@1382: ingo@1382: for (Layer layer: layers) { ingo@1382: if (name.equals(layer.getName())) { ingo@1382: map.removeLayer(layer); ingo@1382: } ingo@1382: } ingo@1382: } ingo@1382: ingo@1382: ingo@1364: @Override ingo@1364: public void onRedrawRequest(RedrawRequestEvent event) { ingo@1382: mapService.doOut(collection, new AsyncCallback() { ingo@1382: public void onFailure(Throwable caught) { ingo@1382: GWT.log("MAP ERROR: " + caught.getMessage()); ingo@1382: } ingo@1382: ingo@1382: public void onSuccess(MapConfig c) { ingo@1382: themePanel.updateCollection(); ingo@1382: } ingo@1382: }); ingo@1364: } ingo@1364: ingo@1364: ingo@1376: protected void setFloodmap(FloodMap floodMap) { ingo@1376: this.floodMap = floodMap; ingo@1376: } ingo@1376: ingo@1376: ingo@1306: protected Map getMap() { ingo@1306: return floodMap.getMap(); ingo@1306: } ingo@1306: ingo@1306: ingo@1382: protected ThemePanel getThemePanel() { ingo@1382: return themePanel; ingo@1382: } ingo@1382: ingo@1382: ingo@825: protected String getGeoJSONFromDynamic(ArtifactDescription desc) { ingo@825: DataList list = desc.getCurrentData(); ingo@825: ingo@835: if (list == null) { ingo@835: return null; ingo@835: } ingo@835: ingo@825: List datas = list.getAll(); ingo@825: for (Data data: datas) { ingo@825: String key = data.getLabel(); ingo@825: ingo@825: if (key != null && key.equals(BARRIERS_PARAMETER_KEY)) { ingo@825: DataItem def = data.getDefault(); ingo@825: ingo@825: if (def != null) { ingo@825: return def.getStringValue(); ingo@825: } ingo@825: } ingo@825: } ingo@825: ingo@825: return null; ingo@825: } ingo@825: ingo@825: ingo@825: protected String getGeoJSONFromStatic(ArtifactDescription desc) { ingo@825: // TODO Implement this method, if there are reachable states right after ingo@825: // the floodmap state - which is currently not the case. ingo@825: return null; ingo@825: } ingo@825: ingo@825: ingo@823: public ThemeList getThemeList() { ingo@823: return collection.getThemeList(mode.getName()); ingo@823: } ingo@823: ingo@823: ingo@823: public String getSrid() { ingo@823: ThemeList themeList = getThemeList(); ingo@823: ingo@823: int num = themeList.getThemeCount(); ingo@823: ingo@823: for (int i = 1; i <= num; i++) { ingo@823: AttributedTheme theme = (AttributedTheme) themeList.getThemeAt(i); ingo@835: ingo@835: if (theme == null) { ingo@835: continue; ingo@835: } ingo@835: ingo@823: String srid = theme.getAttr("srid"); ingo@823: ingo@823: if (srid != null && srid.length() > 0) { ingo@823: return srid; ingo@823: } ingo@823: } ingo@823: ingo@823: return DEFAULT_SRID; ingo@823: } ingo@823: ingo@823: ingo@806: protected Bounds boundsFromString(String bounds) { ingo@1376: GWT.log("Create Bounds from String: '" + bounds + "'"); ingo@806: if (bounds == null || bounds.length() == 0) { ingo@806: return null; ingo@806: } ingo@806: ingo@806: String[] values = bounds.split(" "); ingo@806: ingo@806: if (values == null || values.length < 4) { ingo@806: return null; ingo@806: } ingo@806: ingo@806: try { ingo@806: return new Bounds( ingo@806: Double.valueOf(values[0]), ingo@823: Double.valueOf(values[1]), ingo@806: Double.valueOf(values[2]), ingo@823: Double.valueOf(values[3])); ingo@806: } ingo@806: catch (NumberFormatException nfe) {} ingo@806: ingo@806: return null; ingo@806: } ingo@806: ingo@806: ingo@1382: public Layer createWMSLayer(Theme theme) { ingo@806: if (theme == null) { ingo@806: return null; ingo@806: } ingo@806: ingo@806: AttributedTheme at = (AttributedTheme) theme; ingo@806: ingo@806: String type = at.getAttr("name"); ingo@806: String desc = at.getAttr("description"); ingo@806: String url = at.getAttr("url"); ingo@806: String layers = at.getAttr("layers"); ingo@806: ingo@806: if (url == null || layers == null) { ingo@806: return null; ingo@806: } ingo@806: ingo@806: //boolean baseLayer = type.equals("floodmap.wmsbackground"); ingo@797: ingo@797: WMSParams params = new WMSParams(); ingo@797: params.setLayers(layers); ingo@797: params.setFormat("image/png"); ingo@806: params.setIsTransparent(true); ingo@797: ingo@823: WMSOptions opts = new WMSOptions(); ingo@823: opts.setProjection("EPSG:" + getSrid()); ingo@823: opts.setSingleTile(true); ingo@823: opts.setRatio(1); ingo@823: ingo@823: WMS wms = new WMS(desc, url, params, opts); ingo@806: wms.setIsVisible(at.getActive() == 1); ingo@806: wms.setIsBaseLayer(false); ingo@797: ingo@806: return wms; ingo@797: } ingo@797: ingo@797: raimund@1386: protected MapToolbar createControlPanel() { raimund@1386: return new MapToolbar(this, floodMap, false); ingo@796: } ingo@796: ingo@796: ingo@796: protected Canvas createThemePanel() { ingo@796: Canvas c = new Canvas(); ingo@1327: c.setMinWidth(300); ingo@1327: c.setWidth(300); ingo@796: c.setHeight100(); ingo@1327: c.setCanDragResize(true); ingo@797: c.setBorder("1px solid black"); ingo@796: ingo@806: themePanel = new MapThemePanel( ingo@1306: collection, ingo@1306: mode, ingo@1382: this, ingo@1306: new MapThemePanel.ActivateCallback() { ingo@806: public void activate(Theme theme, boolean active) { ingo@806: activateTheme(theme, active); ingo@806: } ingo@1306: }, ingo@1306: new MapThemePanel.ThemeMovedCallback() { ingo@1306: public void onThemeMoved(Theme theme, int oldIdx, int newIdx) { ingo@1306: // this code synchronizes the ThemePanel and the OpenLayers ingo@1306: // internal order of layers. ingo@1306: String name = theme.getDescription(); ingo@1306: Map map = getMap(); ingo@1306: Layer[] layers = map.getLayersByName(name); ingo@1306: ingo@1306: if (layers == null || layers.length == 0) { ingo@1306: GWT.log("Error: Cannot find layer '" + name + "'"); ingo@1306: return; ingo@1306: } ingo@1306: ingo@1306: map.raiseLayer(layers[0], (newIdx-oldIdx)*-1); ingo@1306: map.zoomTo(map.getZoom()-1); ingo@1306: map.zoomTo(map.getZoom()+1); ingo@1306: } ingo@1377: }, ingo@1377: new MapThemePanel.LayerZoomCallback() { ingo@1377: public void onLayerZoom(Theme theme, String extent) { ingo@1377: Bounds zoomTo = boundsFromString(extent); ingo@1377: ingo@1377: if (zoomTo == null) { ingo@1377: GWT.log("WARNING: No valid bounds for zooming found!"); ingo@1377: return; ingo@1377: } ingo@1377: ingo@1377: getMap().zoomToExtent(zoomTo); ingo@1377: } ingo@1306: } ingo@1306: ); ingo@806: c.addChild(themePanel); ingo@796: ingo@796: return c; ingo@796: } ingo@806: ingo@806: ingo@806: protected void activateTheme(Theme theme, boolean active) { ingo@806: String name = theme.getDescription(); ingo@806: Layer layer = floodMap.getMap().getLayerByName(name); ingo@806: ingo@1382: GWT.log("Set visibility of '" + name + "': " + active); ingo@1382: ingo@806: if (layer != null) { ingo@806: layer.setIsVisible(active); ingo@806: } ingo@806: } ingo@825: ingo@825: ingo@825: protected void saveBarriers() { ingo@825: Vector layer = floodMap.getBarrierLayer(); ingo@825: ingo@825: GeoJSON format = new GeoJSON(); ingo@825: String features = format.write(layer.getFeatures()); ingo@825: ingo@825: DataItem item = new DefaultDataItem( ingo@825: BARRIERS_PARAMETER_KEY, BARRIERS_PARAMETER_KEY, features); ingo@825: ingo@825: Data data = new DefaultData( ingo@825: BARRIERS_PARAMETER_KEY, BARRIERS_PARAMETER_KEY, "String", ingo@825: new DataItem[] {item} ); ingo@825: ingo@825: Config config = Config.getInstance(); ingo@825: final String url = config.getServerUrl(); ingo@825: final String locale = config.getLocale(); ingo@825: ingo@825: feedService.go(url, locale, getArtifact(), new Data[] { data }, ingo@825: new AsyncCallback() { ingo@825: public void onFailure(Throwable caught) { ingo@825: GWT.log("Could not save barrier geometries: " + ingo@825: caught.getMessage()); ingo@825: } ingo@825: ingo@825: public void onSuccess(Artifact artifact) { ingo@825: GWT.log("Successfully saved barrier geometries."); ingo@825: } ingo@825: } ingo@825: ); ingo@825: } ingo@796: } ingo@796: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :