view flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapOutputTab.java @ 4205:0dd8963cec9c

Set also the width of the GaugeTree when resizing the GaugePanel GWT is no longer able to calculate and set the correct width of the GaugeTree since the GaugeTree is added via a Canvas wrapper. Therefore set the width manually when resizing the GaugeTree.
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 22 Oct 2012 15:33:16 +0200
parents 61020a61ed38
children c9dcce9448f2
line wrap: on
line source
package de.intevation.flys.client.client.ui.map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;

import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.events.ResizedEvent;
import com.smartgwt.client.widgets.events.ResizedHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.events.TabSelectedEvent;
import com.smartgwt.client.widgets.tab.events.TabSelectedHandler;

import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.client.event.RedrawRequestEvent;
import de.intevation.flys.client.client.event.RedrawRequestHandler;
import de.intevation.flys.client.client.services.LoadArtifactService;
import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
import de.intevation.flys.client.client.services.MapOutputService;
import de.intevation.flys.client.client.services.MapOutputServiceAsync;
import de.intevation.flys.client.client.services.StepForwardService;
import de.intevation.flys.client.client.services.StepForwardServiceAsync;
import de.intevation.flys.client.client.ui.CollectionView;
import de.intevation.flys.client.client.ui.OutputTab;
import de.intevation.flys.client.client.ui.ThemePanel;
import de.intevation.flys.client.shared.model.Artifact;
import de.intevation.flys.client.shared.model.ArtifactDescription;
import de.intevation.flys.client.shared.model.AttributedTheme;
import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.shared.model.Data;
import de.intevation.flys.client.shared.model.DataItem;
import de.intevation.flys.client.shared.model.DataList;
import de.intevation.flys.client.shared.model.DefaultData;
import de.intevation.flys.client.shared.model.DefaultDataItem;
import de.intevation.flys.client.shared.model.MapConfig;
import de.intevation.flys.client.shared.model.OutputMode;
import de.intevation.flys.client.shared.model.Recommendation;
import de.intevation.flys.client.shared.model.Theme;
import de.intevation.flys.client.shared.model.ThemeList;
import de.intevation.flys.client.shared.model.WMSLayer;

import java.util.List;

import org.gwtopenmaps.openlayers.client.Bounds;
import org.gwtopenmaps.openlayers.client.Map;
import org.gwtopenmaps.openlayers.client.event.VectorFeatureAddedListener;
import org.gwtopenmaps.openlayers.client.event.VectorFeatureRemovedListener;
import org.gwtopenmaps.openlayers.client.feature.VectorFeature;
import org.gwtopenmaps.openlayers.client.format.GeoJSON;
import org.gwtopenmaps.openlayers.client.layer.Layer;
import org.gwtopenmaps.openlayers.client.layer.Vector;
import org.gwtopenmaps.openlayers.client.layer.WMS;
import org.gwtopenmaps.openlayers.client.layer.WMSOptions;
import org.gwtopenmaps.openlayers.client.layer.WMSParams;


public class MapOutputTab
extends      OutputTab
implements   RedrawRequestHandler, ExternalWMSWindow.LayerLoader, TabSelectedHandler {

    public static final String DEFAULT_SRID = "4326";

    public static final String BARRIERS_PARAMETER_KEY = "uesk.barriers";

    public static final String WSPLGEN_FACET = "floodmap.wsplgen";

    public static final String EXTERNAL_WMS_FACTORY = "externalwmsfactory";


    protected StepForwardServiceAsync feedService =
        GWT.create(StepForwardService.class);

    protected MapOutputServiceAsync mapService =
        GWT.create(MapOutputService.class);

    /** Service handle to clone and add artifacts to collection. */
    protected LoadArtifactServiceAsync loadArtifactService =
        GWT.create(LoadArtifactService.class);

    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    protected MapToolbar controlPanel;
    protected ThemePanel themePanel;
    protected Canvas     themePanelCanvas;
    protected Widget     mapPanel;
    protected Canvas mapPanelCanvas;

    protected FloodMap floodMap;


    public MapOutputTab(
        String         title,
        Collection     collection,
        OutputMode     mode,
        CollectionView collectionView
    ){
        super(title, collection, collectionView, mode);

        collectionView.registerTabHandler(this);

        mapService.doOut(collection, new AsyncCallback<MapConfig>() {
                @Override
                public void onFailure(Throwable caught) {
                    GWT.log("MAP ERROR: " + caught.getMessage());
                }

                @Override
                public void onSuccess(MapConfig c) {
                    GWT.log("MAP SUCCESS!");

                    Bounds max     = boundsFromString(c.getMaxExtent());
                    Bounds initial = boundsFromString(c.getInitialExtent());

                    if (initial == null) {
                        GWT.log("Warning: No initial extent set.");
                        initial = max;
                    }

                    setFloodmap(new FloodMap(c.getSrid(), max));

                    initLayout();
                    initBarriers();

                    GWT.log("MAX EXTENT: " + max);
                    GWT.log("ZOOM TO: " + initial);
                    getMap().zoomToExtent(initial);
                }
            }
        );
    }


    protected void initLayout() {
        VLayout rootLayout = new VLayout();
        rootLayout.setHeight100();
        rootLayout.setWidth100();
        rootLayout.setMembersMargin(2);

        final HLayout hlayout = new HLayout();
        hlayout.setMembersMargin(2);

        this.themePanelCanvas = createThemePanel();

        controlPanel = createControlPanel();
        //mapPanel     = new Image();
        //((Image)mapPanel).setUrl("http://www.hedweb.com/animimag/cool-pony.jpg");
        mapPanel = floodMap.getMapWidget();
        hlayout.addMember(themePanelCanvas);
        hlayout.addMember(mapPanel);

        rootLayout.addMember(controlPanel);
        rootLayout.addMember(hlayout);

        hlayout.addResizedHandler(new ResizedHandler() {
            @Override
            public void onResized(ResizedEvent e) {
                int height = hlayout.getHeight();
                int width  = hlayout.getWidth() -
                        (themePanelCanvas.isVisible() ? themePanelCanvas.getWidth() : 0);

                height = height * 99 / 100;
                width  = width  * 99 / 100;

                String w = String.valueOf(width) + "px";
                String h = String.valueOf(height) + "px";

                mapPanel.setSize(w, h);
            }
        });

        setPane(rootLayout);
    }


    protected void initBarriers() {
        Vector vector = floodMap.getBarrierLayer();
        vector.addVectorFeatureAddedListener(
            new VectorFeatureAddedListener() {
                @Override
                public void onFeatureAdded(FeatureAddedEvent e) {
                    saveBarriers();
                }
            }
        );

        vector.addVectorFeatureRemovedListener(
            new VectorFeatureRemovedListener() {
                @Override
                public void onFeatureRemoved(FeatureRemovedEvent e) {
                    saveBarriers();
                }
            }
        );


        Artifact artifact = getArtifact();

        if (artifact == null) {
            return;
        }

        ArtifactDescription desc = artifact.getArtifactDescription();

        String geojson = getGeoJSONFromStatic(desc);
        geojson        = geojson != null ? geojson : getGeoJSONFromDynamic(desc);

        if (geojson == null || geojson.length() == 0) {
            GWT.log("No geojson string found -> no barriers existing.");
            return;
        }

        GeoJSON reader = new GeoJSON();
        VectorFeature[] features = reader.read(geojson);

        vector.addFeatures(features);
    }


    public void addLayer(Layer layer) {
        FloodMap map = getFloodmap();

        if (map != null) {
            GWT.log("Add new layer '" + layer.getName() + "' to map.");
            map.addLayer(layer);
        }
    }


    public void removeLayer(String name) {
        Map map = getMap();

        Layer[] layers = map.getLayers();

        for (Layer layer: layers) {
            if (name.equals(layer.getName())) {
                map.removeLayer(layer);
            }
        }
    }


    @Override
    public void onRedrawRequest(RedrawRequestEvent event) {
        mapService.doOut(collection, new AsyncCallback<MapConfig>() {
            @Override
            public void onFailure(Throwable caught) {
                GWT.log("MAP ERROR: " + caught.getMessage());
            }

            @Override
            public void onSuccess(MapConfig c) {
                GWT.log("We want to refresh the map now!");
                themePanel.updateCollection();
                getFloodmap().update();
            }
        });
    }


    @Override
    public void load(List<WMSLayer> toLoad) {
        GWT.log("The user wants to add " + toLoad.size() + " new WMS layers.");

        int len = toLoad.size();

        Recommendation[] recom = new Recommendation[len];

        for (int i = 0; i < len; i++) {
            WMSLayer w = toLoad.get(i);

            String ids = w.getServer() + ";" + w.getName() + ";" + w.getTitle();
            recom[i] = new Recommendation(EXTERNAL_WMS_FACTORY, ids);
        }

        Collection c = getCollection();

        Config config = Config.getInstance();
        String locale = config.getLocale();

        loadArtifactService.loadMany(c, recom, EXTERNAL_WMS_FACTORY, locale,
            new AsyncCallback<Artifact[]>() {

                @Override
                public void onFailure(Throwable throwable) {
                    SC.warn(MSG.getString(throwable.getMessage()));
                }

                @Override
                public void onSuccess(Artifact[] newArtifacts) {
                    getThemePanel().updateCollection();
                }
            }
        );
    }


    protected void setFloodmap(FloodMap floodMap) {
        this.floodMap = floodMap;
    }


    protected FloodMap getFloodmap() {
        return floodMap;
    }


    protected Map getMap() {
        return floodMap.getMap();
    }


    protected ThemePanel getThemePanel() {
        return themePanel;
    }


    protected String getGeoJSONFromDynamic(ArtifactDescription desc) {
        DataList list = desc.getCurrentData();

        if (list == null) {
            return null;
        }

        List<Data> datas = list.getAll();
        for (Data data: datas) {
            String key = data.getLabel();

            if (key != null && key.equals(BARRIERS_PARAMETER_KEY)) {
                DataItem def = data.getDefault();

                if (def != null) {
                    return def.getStringValue();
                }
            }
        }

        return null;
    }


    protected String getGeoJSONFromStatic(ArtifactDescription desc) {
        // TODO Implement this method, if there are reachable states right after
        // the floodmap state - which is currently not the case.
        return null;
    }


    public ThemeList getThemeList() {
        return collection.getThemeList(mode.getName());
    }


    public String getSrid() {
        ThemeList themeList = getThemeList();

        int num = themeList.getThemeCount();

        for (int i = 1; i <= num; i++) {
            AttributedTheme theme = (AttributedTheme) themeList.getThemeAt(i);

            if (theme == null) {
                continue;
            }

            String srid = theme.getAttr("srid");

            if (srid != null && srid.length() > 0) {
                return srid;
            }
        }

        return DEFAULT_SRID;
    }


    protected Bounds boundsFromString(String bounds) {
        GWT.log("Create Bounds from String: '" + bounds + "'");
        if (bounds == null || bounds.length() == 0) {
            return null;
        }

        String[] values = bounds.split(" ");

        if (values == null || values.length < 4) {
            return null;
        }

        try {
            return new Bounds(
                Double.valueOf(values[0]),
                Double.valueOf(values[1]),
                Double.valueOf(values[2]),
                Double.valueOf(values[3]));
        }
        catch (NumberFormatException nfe) {}

        return null;
    }


    public Layer createWMSLayer(Theme theme) {
        if (theme == null) {
            return null;
        }

        AttributedTheme at = (AttributedTheme) theme;

        //String type      = at.getAttr("name");
        //String desc      = at.getAttr("description");
        String url       = at.getAttr("url");
        String layers    = at.getAttr("layers");

        if (url == null || layers == null) {
            return null;
        }

        //boolean baseLayer = type.equals("floodmap.wmsbackground");

        WMSParams params = new WMSParams();
        params.setLayers(layers);
        params.setFormat("image/png");
        params.setIsTransparent(true);

        WMSOptions opts = new WMSOptions();
        opts.setProjection("EPSG:" + getSrid());
        opts.setSingleTile(true);
        opts.setRatio(1);

        WMS wms = new WMS(layers, url, params, opts);
        wms.setIsVisible(at.getActive() == 1);
        wms.setIsBaseLayer(false);

        return wms;
    }


    protected MapToolbar createControlPanel() {
        return new MapToolbar(this, floodMap, false);
    }


    protected Canvas createThemePanel() {
        Canvas c = new Canvas();
        c.setMinWidth(300);
        c.setWidth(300);
        c.setHeight100();
        c.setCanDragResize(true);
        c.setBorder("1px solid black");

        themePanel = new MapThemePanel(
            this.getCollectionView(),
            mode,
            this,
            new MapThemePanel.ActivateCallback() {
                @Override
                public void activate(Theme theme, boolean active) {
                    activateTheme(theme, active);
                }
            },
            new MapThemePanel.ThemeMovedCallback() {
                @Override
                public void onThemeMoved(Theme theme, int oldIdx, int newIdx) {
                    // this code synchronizes the ThemePanel and the OpenLayers
                    // internal order of layers.
                    AttributedTheme at = (AttributedTheme) theme;

                    String    name = at.getAttr("layers");
                    Map        map = getMap();
                    Layer[] layers = map.getLayersByName(name);

                    if (layers == null || layers.length == 0) {
                        GWT.log("Error: Cannot find layer '" + name + "'");
                        return;
                    }

                    map.raiseLayer(layers[0], (newIdx-oldIdx)*-1);
                    map.zoomTo(map.getZoom()-1);
                    map.zoomTo(map.getZoom()+1);
                }
            },
            new MapThemePanel.LayerZoomCallback() {
                @Override
                public void onLayerZoom(Theme theme, String extent) {
                    Bounds zoomTo = boundsFromString(extent);

                    if (zoomTo == null) {
                        GWT.log("WARNING: No valid bounds for zooming found!");
                        return;
                    }

                    getMap().zoomToExtent(zoomTo);
                }
            }
        );
        themePanel.addRedrawRequestHandler(this);
        c.addChild(themePanel);

        return c;
    }


    protected void activateTheme(Theme theme, boolean active) {
        AttributedTheme at = (AttributedTheme) theme;

        String name = at.getAttr("layers");
        Layer layer = floodMap.getMap().getLayerByName(name);

        GWT.log("Set visibility of '" + name + "': " + active);

        if (layer != null) {
            layer.setIsVisible(active);
        }
    }


    protected void saveBarriers() {
        Vector layer = floodMap.getBarrierLayer();

        GeoJSON format   = new GeoJSON();
        String  features = format.write(layer.getFeatures());

        DataItem item = new DefaultDataItem(
            BARRIERS_PARAMETER_KEY, BARRIERS_PARAMETER_KEY, features);

        Data data = new DefaultData(
            BARRIERS_PARAMETER_KEY, BARRIERS_PARAMETER_KEY, "String",
            new DataItem[] {item} );

        Config config       = Config.getInstance();
        final String locale = config.getLocale();

        feedService.go(locale, getArtifact(), new Data[] { data },
            new AsyncCallback<Artifact>() {
                @Override
                public void onFailure(Throwable caught) {
                    GWT.log("Could not save barrier geometries: " +
                        caught.getMessage());
                }

                @Override
                public void onSuccess(Artifact artifact) {
                    GWT.log("Successfully saved barrier geometries.");
                }
            }
        );
    }


    @Override
    public void onTabSelected(TabSelectedEvent tse) {
        if(floodMap == null) {
            return;
        }
        if(this.equals(tse.getTab())) {
            floodMap.activateScaleLine(true);
        }
        else {
            controlPanel.activateMeasureControl(false);
            floodMap.activateScaleLine(false);
        }
    }

    public void toogleThemePanel() {
        this.themePanelCanvas.setVisible(!themePanelCanvas.isVisible());
        this.themePanelCanvas.setSize(themePanelCanvas.getWidthAsString(),
                                       themePanelCanvas.getHeightAsString());
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org