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@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@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@796: public class MapOutputTab extends OutputTab { 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@796: protected CollectionView parent; ingo@796: 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@796: super(title, collection, mode); ingo@796: this.parent = collectionView; ingo@796: ingo@823: floodMap = new FloodMap(getSrid(), getMaxExtent()); ingo@797: ingo@796: initLayout(); ingo@797: initLayers(); ingo@825: initBarriers(); 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: ingo@798: final Canvas wrapper = new Canvas(); ingo@798: wrapper.setWidth100(); ingo@798: wrapper.setHeight100(); ingo@798: ingo@800: controlPanel = createControlPanel(wrapper); ingo@800: mapPanel = floodMap.getMapWidget(); ingo@806: Canvas themePanelWrapper = createThemePanel(); ingo@800: 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@798: wrapper.addChild(layout); ingo@797: ingo@798: HLayout hlayout = new HLayout(); ingo@798: hlayout.setHeight("*"); ingo@798: hlayout.setWidth100(); ingo@798: hlayout.setMembersMargin(2); ingo@797: ingo@806: hlayout.addMember(themePanelWrapper); ingo@798: hlayout.addMember(wrapper); ingo@798: ingo@798: rootLayout.addMember(controlPanel); ingo@798: rootLayout.addMember(hlayout); ingo@798: ingo@798: wrapper.addResizedHandler(new ResizedHandler() { ingo@798: public void onResized(ResizedEvent e) { ingo@798: Integer height = wrapper.getHeight(); ingo@798: Integer width = wrapper.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@797: protected void initLayers() { ingo@806: ThemeList themeList = themePanel.getThemeList(); ingo@797: ingo@806: int num = themeList.getThemeCount(); ingo@806: ingo@1269: Map map = floodMap.getMap(); ingo@1269: Bounds extent = null; ingo@1269: Bounds wsplgenExtent = null; ingo@806: ingo@806: for (int i = 1; i <= num; i++) { ingo@806: Theme theme = themeList.getThemeAt(i); ingo@806: Layer layer = createWMSLayer(theme); ingo@806: ingo@806: if (layer == null) { ingo@806: continue; ingo@806: } ingo@806: ingo@806: map.addLayer(layer); ingo@806: ingo@806: AttributedTheme at = (AttributedTheme) theme; ingo@806: String tmp = at.getAttr("extent"); ingo@806: ingo@1269: if (WSPLGEN_FACET.equals(at.getFacet())) { ingo@1269: // if there is a wsplgen layer, we want to zoom to ingo@1269: // that place initially ingo@1269: wsplgenExtent = boundsFromString(tmp); ingo@1269: } ingo@1269: ingo@806: if (theme.getActive() == 1) { ingo@806: if (extent == null) { ingo@806: extent = boundsFromString(tmp); ingo@806: } ingo@806: else { ingo@806: Bounds b = boundsFromString(tmp); ingo@806: ingo@806: if (b != null) { ingo@806: extent.extend(b); ingo@806: } ingo@806: } ingo@806: } ingo@806: } ingo@806: ingo@1269: extent = wsplgenExtent != null ? wsplgenExtent : extent; ingo@1269: ingo@823: GWT.log("Maps initial extent = " + extent); ingo@823: ingo@823: map.zoomToExtent(extent != null ingo@806: ? extent ingo@806: : new Bounds(-90, -180, 90, 180)); ingo@806: } ingo@806: ingo@806: 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@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@825: public Artifact getArtifact() { ingo@825: return parent.getArtifact(); 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@823: public Bounds getMaxExtent() { ingo@823: ThemeList themeList = getThemeList(); ingo@823: ingo@823: int num = themeList.getThemeCount(); ingo@823: ingo@823: Bounds extent = null; 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 tmp = theme.getAttr("extent"); ingo@823: ingo@823: if (theme.getActive() == 1) { ingo@823: if (extent == null) { ingo@823: extent = boundsFromString(tmp); ingo@823: } ingo@823: else { ingo@823: Bounds b = boundsFromString(tmp); ingo@823: ingo@823: if (b != null) { ingo@823: extent.extend(b); ingo@823: } ingo@823: } ingo@823: } ingo@823: } ingo@823: ingo@823: return extent; ingo@823: } ingo@823: ingo@823: ingo@806: protected Bounds boundsFromString(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@806: protected 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: ingo@825: protected MapToolbar createControlPanel(Canvas wrapper) { ingo@835: return new MapToolbar(floodMap, wrapper, false); ingo@796: } ingo@796: ingo@796: ingo@796: protected Canvas createThemePanel() { ingo@796: Canvas c = new Canvas(); ingo@796: c.setWidth(200); ingo@796: c.setHeight100(); ingo@797: c.setBorder("1px solid black"); ingo@796: ingo@806: themePanel = new MapThemePanel( ingo@806: collection, mode, new MapThemePanel.ActivateCallback() { ingo@806: public void activate(Theme theme, boolean active) { ingo@806: activateTheme(theme, active); ingo@806: } ingo@806: }); 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@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 :