view flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapOutputTab.java @ 4330:93e023131546

Removed the legend images from map theme panel.
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 30 Oct 2012 15:35:09 +0100
parents c9dcce9448f2
children c84630d544a1
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.OutputParameterChangeEvent;
import de.intevation.flys.client.client.event.OutputParameterChangeHandler;
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, OutputParameterChangeHandler {

    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(200);
        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) {
                    fireActivateTheme(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);
        themePanel.addOutputParameterChangeHandler(this);
        c.addChild(themePanel);

        return c;
    }


    private void fireActivateTheme(Theme theme, boolean active) {
        activateTheme(theme, active);
    }


    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());
    }


    @Override
    public void onOutputParameterChanged(OutputParameterChangeEvent evt) {
        GWT.log("OutputParameterChanged");
        controlPanel.updateThemes(getThemePanel().getThemeList());
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org