Package org.geomajas.gwt.client.widget

Source Code of org.geomajas.gwt.client.widget.Legend

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.gwt.client.widget;

import java.util.ArrayList;
import java.util.List;

import org.geomajas.configuration.FeatureStyleInfo;
import org.geomajas.geometry.Coordinate;
import org.geomajas.gwt.client.Geomajas;
import org.geomajas.gwt.client.gfx.GraphicsContext;
import org.geomajas.gwt.client.gfx.paintable.Composite;
import org.geomajas.gwt.client.gfx.style.FontStyle;
import org.geomajas.gwt.client.gfx.style.PictureStyle;
import org.geomajas.gwt.client.gfx.style.ShapeStyle;
import org.geomajas.gwt.client.map.MapModel;
import org.geomajas.gwt.client.map.event.LayerChangedHandler;
import org.geomajas.gwt.client.map.event.LayerFilteredEvent;
import org.geomajas.gwt.client.map.event.LayerFilteredHandler;
import org.geomajas.gwt.client.map.event.LayerLabeledEvent;
import org.geomajas.gwt.client.map.event.LayerShownEvent;
import org.geomajas.gwt.client.map.event.LayerStyleChangeEvent;
import org.geomajas.gwt.client.map.event.LayerStyleChangedHandler;
import org.geomajas.gwt.client.map.event.MapModelEvent;
import org.geomajas.gwt.client.map.event.MapModelHandler;
import org.geomajas.gwt.client.map.layer.Layer;
import org.geomajas.gwt.client.map.layer.RasterLayer;
import org.geomajas.gwt.client.map.layer.VectorLayer;
import org.geomajas.gwt.client.spatial.Bbox;
import org.geomajas.gwt.client.spatial.geometry.LineString;
import org.geomajas.gwt.client.widget.event.GraphicsReadyEvent;
import org.geomajas.gwt.client.widget.event.GraphicsReadyHandler;
import org.geomajas.layer.LayerType;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerRegistration;
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;

/**
* <p>
* Widget that shows the styles of the currently visible layers. For vector layers, there can be many styles. Note that
* this widget will react automatically to the visibility status of the layers.
* </p>
*
* @author Frank Wynants
* @author Pieter De Graef
*/
public class Legend extends Canvas {

  private List<HandlerRegistration> registrations = new ArrayList<HandlerRegistration>();

  private HandlerRegistration loadedRegistration;

  private HandlerRegistration resizeRegistration;

  private HandlerRegistration graphicsRegistration;

  private MapModel mapModel;

  private GraphicsWidget widget;

  private GraphicsContext graphics;

  private Composite parentGroup = new Composite("legend-group");

  private FontStyle fontStyle = new FontStyle("#000000", 14, "Arial", "normal", "normal");

  // -------------------------------------------------------------------------
  // Constructor:
  // -------------------------------------------------------------------------

  /**
   * A legend needs to be instantiated with the MapModel that contains (or will contain) the list of layers that this
   * legend should listen to.
   */
  public Legend(MapModel mapModel) {
    super();
    setWidth100();
    setHeight100();
    this.mapModel = mapModel;

    widget = new GraphicsWidget(SC.generateID());
    widget.setBackgroundColor("#FFFFFF");
    // adding the graphics here causes problems when embedding in HTML !
    // addChild(widget);

    graphics = widget.getVectorContext();

    loadedRegistration = mapModel.addMapModelHandler(new MapModelHandler() {

      public void onMapModelChange(MapModelEvent event) {
        initialize();
      }
    });

    resizeRegistration = addResizedHandler(new ResizedHandler() {

      public void onResized(ResizedEvent event) {
        // Triggered by the render method (setHeight):
        widget.setSize(getWidthAsString(), getHeightAsString());
        widget.resize();
      }
    });

    graphicsRegistration = widget.addGraphicsReadyHandler(new GraphicsReadyHandler() {

      public void onReady(GraphicsReadyEvent event) {
        // Triggered by the resized handler (i.e. we're ready to render the legend):
        renderWithoutResize();
      }
    });
  }

  // -------------------------------------------------------------------------
  // Public methods:
  // -------------------------------------------------------------------------

  /**
   * Render the legend. This triggers a complete redraw.
   */
  public void render() {
    int y = 5;
    for (Layer<?> layer : mapModel.getLayers()) {
      if (layer.isShowing()) {
        if (layer instanceof VectorLayer) {
          VectorLayer vLayer = (VectorLayer) layer;
          y += 21 * vLayer.getLayerInfo().getNamedStyleInfo().getFeatureStyles().size();
        } else if (layer instanceof RasterLayer) {
          y += 20;
        }
      }
    }
    setHeight(y);
  }

  // -------------------------------------------------------------------------
  // Getters and setters:
  // -------------------------------------------------------------------------

  public MapModel getMapModel() {
    return mapModel;
  }

  public FontStyle getFontStyle() {
    return fontStyle;
  }

  public void setFontStyle(FontStyle fontStyle) {
    this.fontStyle = fontStyle;
  }

  // -------------------------------------------------------------------------
  // Private methods:
  // -------------------------------------------------------------------------

  /** Render the legend, without actually resizing the widget. */
  private void renderWithoutResize() {
    graphics.deleteGroup(parentGroup);
    parentGroup = new Composite("legend-group");
    graphics.drawGroup(null, parentGroup);

    // Then go over all layers, to draw styles:
    int lineCount = 0;
    int y = 5;
    for (Layer<?> layer : mapModel.getLayers()) {
      if (layer.isShowing()) {

        // Go over every truly visible layer:
        if (layer instanceof VectorLayer) {
          VectorLayer vLayer = (VectorLayer) layer;

          // For vector layer; loop over the style definitions:
          for (FeatureStyleInfo styleInfo : vLayer.getLayerInfo().getNamedStyleInfo().getFeatureStyles()) {
            ShapeStyle style = new ShapeStyle(styleInfo);
            graphics.drawSymbolDefinition(null, styleInfo.getStyleId(), styleInfo.getSymbol(),
                new ShapeStyle(styleInfo), null);
            lineCount++;

            if (vLayer.getLayerInfo().getLayerType() == LayerType.LINESTRING
                || vLayer.getLayerInfo().getLayerType() == LayerType.MULTILINESTRING) {
              // Lines, draw a LineString;
              Coordinate[] coordinates = new Coordinate[4];
              coordinates[0] = new Coordinate(10, y);
              coordinates[1] = new Coordinate(10 + 10, y + 5);
              coordinates[2] = new Coordinate(10 + 5, y + 10);
              coordinates[3] = new Coordinate(10 + 15, y + 15);
              LineString line = mapModel.getGeometryFactory().createLineString(coordinates);
              graphics.drawLine(parentGroup, "style" + lineCount, line, style);
            } else if (vLayer.getLayerInfo().getLayerType() == LayerType.POLYGON
                || vLayer.getLayerInfo().getLayerType() == LayerType.MULTIPOLYGON) {
              // Polygons: draw a rectangle:
              Bbox rect = new Bbox(10, y, 16, 16);
              graphics.drawRectangle(parentGroup, "style" + lineCount, rect, style);
            } else if (vLayer.getLayerInfo().getLayerType() == LayerType.POINT
                || vLayer.getLayerInfo().getLayerType() == LayerType.MULTIPOINT) {
              // Points: draw a symbol:
              graphics.drawSymbol(parentGroup, "style" + lineCount, new Coordinate(18, y + 8), style,
                  styleInfo.getStyleId());
            }

            // After the style, draw the style's name:
            Coordinate textPosition = new Coordinate(30, y - 2);
            graphics.drawText(parentGroup, "text" + lineCount, styleInfo.getName(), textPosition,
                fontStyle);
            y += 21;
          }
        } else if (layer instanceof RasterLayer) {
          // For raster layers; show a nice symbol:
          lineCount++;

          graphics.drawImage(parentGroup, "style" + lineCount, Geomajas.getIsomorphicDir()
              + "geomajas/osgeo/layer-raster.png", new Bbox(10, y, 16, 16), new PictureStyle(1));
          Coordinate textPosition = new Coordinate(30, y - 2);
          graphics.drawText(parentGroup, "text" + lineCount, layer.getLabel(), textPosition, fontStyle);
          y += 20;
        }
      }
    }
  }

  /** Called when the MapModel configuration has been loaded. */
  private void initialize() {
    addChild(widget);
    for (Layer<?> layer : mapModel.getLayers()) {
      registrations.add(layer.addLayerChangedHandler(new LayerChangedHandler() {

        public void onLabelChange(LayerLabeledEvent event) {
        }

        public void onVisibleChange(LayerShownEvent event) {
          GWT.log("Legend: onVisibleChange()");
          render();
        }

      }));
      registrations.add(layer.addLayerStyleChangedHandler(new LayerStyleChangedHandler() {

        public void onLayerStyleChange(LayerStyleChangeEvent event) {
          GWT.log("Legend: onLayerStyleChange()");
          render();
        }
      }));
    }
    for (final VectorLayer layer : mapModel.getVectorLayers()) {
      layer.addLayerFilteredHandler(new LayerFilteredHandler() {

        public void onFilterChange(LayerFilteredEvent event) {
          render();
        }
      });
    }
    GWT.log("Legend.initialize");
    render();
  }

  /** Remove all handlers on unload. */
  protected void onUnload() {
    if (registrations != null) {
      for (HandlerRegistration registration : registrations) {
        registration.removeHandler();
      }
    }
    loadedRegistration.removeHandler();
    resizeRegistration.removeHandler();
    graphicsRegistration.removeHandler();
    super.onUnload();
  }
}
TOP

Related Classes of org.geomajas.gwt.client.widget.Legend

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.