org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.java

Source

/*--------------- Kalypso-Header --------------------------------------------------------------------
    
 This file is part of kalypso.
 Copyright (C) 2004, 2005 by:
    
 Technical University Hamburg-Harburg (TUHH)
 Institute of River and coastal engineering
 Denickestr. 22
 21073 Hamburg, Germany
 http://www.tuhh.de/wb
    
 and
    
 Bjoernsen Consulting Engineers (BCE)
 Maria Trost 3
 56070 Koblenz, Germany
 http://www.bjoernsen.de
    
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
    
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
    
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
 Contact:
    
 E-Mail:
 belger@bjoernsen.de
 schlienger@bjoernsen.de
 v.doemming@tuhh.de
    
 ---------------------------------------------------------------------------------------------------*/
package org.kalypso.ogc.gml.map.widgets;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.kalypso.commons.command.ICommandTarget;
import org.kalypso.gmlschema.feature.IFeatureType;
import org.kalypso.gmlschema.property.IPropertyType;
import org.kalypso.ogc.gml.IKalypsoTheme;
import org.kalypso.ogc.gml.map.IMapPanel;
import org.kalypso.ogc.gml.map.utilities.MapUtilities;
import org.kalypso.ogc.gml.map.utilities.tooltip.ToolTipRenderer;
import org.kalypso.ogc.gml.outline.ViewContentOutline;
import org.kalypso.ogc.gml.widgets.AbstractWidget;
import org.kalypso.ui.editor.mapeditor.GisMapOutlinePage;
import org.kalypso.ui.editor.mapeditor.views.IWidgetWithOptions;
import org.kalypso.ui.editor.mapeditor.views.MapWidgetView;
import org.kalypso.ui.internal.i18n.Messages;
import org.kalypsodeegree.graphics.displayelements.DisplayElement;
import org.kalypsodeegree.graphics.sld.CssParameter;
import org.kalypsodeegree.graphics.sld.PolygonSymbolizer;
import org.kalypsodeegree.graphics.sld.Stroke;
import org.kalypsodeegree.model.feature.Feature;
import org.kalypsodeegree.model.geometry.GM_Envelope;
import org.kalypsodeegree.model.geometry.GM_Object;
import org.kalypsodeegree.model.geometry.GM_Point;
import org.kalypsodeegree_impl.graphics.displayelements.DisplayElementFactory;
import org.kalypsodeegree_impl.graphics.sld.PolygonSymbolizer_Impl;
import org.kalypsodeegree_impl.graphics.sld.Stroke_Impl;

/**
 * This tool helps to find elements on the map. The elements will be searched only in selected layers. Searching will be
 * done for all inserted values, last element found will be centered on the map, in case of filled "X" and "Y" fields
 * the shown position will be centered always according to this coordinates.
 * 
 * @author ig
 */
public class FindElementMapWidget extends AbstractWidget implements IWidgetWithOptions {
    private final FindElementWidgetFace m_widgetFace = new FindElementWidgetFace(this);

    private final ToolTipRenderer m_tooltip = new ToolTipRenderer();

    private IMapPanel m_mapPanel = null;

    private final ISelectionChangedListener m_selectionListener = new ISelectionChangedListener() {
        @Override
        public void selectionChanged(final SelectionChangedEvent event) {
            handleSelectionChanged(event.getSelection());
        }
    };

    private ISelectionProvider m_selectionProvider = null;

    private IKalypsoTheme[] m_themesAct;

    private final int m_maxStrLen = 500;

    public FindElementMapWidget() {
        this(Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.1"), //$NON-NLS-1$
                Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.2")); //$NON-NLS-1$
    }

    public FindElementMapWidget(final String name, final String toolTip) {
        super(name, toolTip);
    }

    @Override
    public void activate(final ICommandTarget commandPoster, final IMapPanel mapPanel) {
        super.activate(commandPoster, mapPanel);

        m_mapPanel = getMapPanel();

        // TODO: what happens if active theme changes? -> map modell listener?

        final ContentOutline outlineView = findOutlineView();
        if (outlineView == null) {
            m_themesAct = m_mapPanel.getMapModell().getAllThemes();
            m_mapPanel.setMessage(Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.1")); //$NON-NLS-1$
            return;
        }

        // REMARK: we get selection from outline, so outlines mapPanel should be the same as the widgets ones
        final IMapPanel outlineMapPanel = findOutlineMapPanel(outlineView);
        if (outlineMapPanel != mapPanel) {
            m_mapPanel.setMessage(Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.2")); //$NON-NLS-1$
            return;
        }

        m_selectionProvider = outlineView.getSite().getSelectionProvider();
        m_selectionProvider.addSelectionChangedListener(m_selectionListener);

        handleSelectionChanged(m_selectionProvider.getSelection());
    }

    public static IMapPanel findOutlineMapPanel(final ContentOutline outlineView) {
        final IPage currentPage = outlineView.getCurrentPage();
        if (currentPage instanceof GisMapOutlinePage)
            return ((GisMapOutlinePage) currentPage).getMapPanel();

        return null;
    }

    public static IWorkbenchPage findActivePage() {
        final IWorkbench workbench = PlatformUI.getWorkbench();
        final IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();

        return window.getActivePage();

    }

    public static ContentOutline findOutlineView() {
        final IWorkbenchPage activePage = findActivePage();

        return (ViewContentOutline) activePage.findView(ViewContentOutline.ID);
    }

    @Override
    public Control createControl(final Composite parent, final FormToolkit toolkit) {
        return m_widgetFace.createControl(toolkit, parent);
    }

    @Override
    public void disposeControl() {
        m_widgetFace.clear();
    }

    @Override
    public void finish() {
        super.finish();

        if (m_selectionProvider != null) {
            m_selectionProvider.removeSelectionChangedListener(m_selectionListener);
            m_selectionProvider = null;
        }
    }

    protected void handleSelectionChanged(final ISelection selection) {
        final List<IKalypsoTheme> themes = new ArrayList<>();
        final IStructuredSelection sel = (IStructuredSelection) selection;
        final Object[] selectedElements = sel.toArray();
        for (final Object object : selectedElements) {
            final IKalypsoTheme theme = findTheme(object);
            if (theme != null)
                themes.add(theme);
        }

        m_themesAct = themes.toArray(new IKalypsoTheme[themes.size()]);

        if (ArrayUtils.isEmpty(m_themesAct)) {
            m_tooltip.setTooltip(Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.11")); //$NON-NLS-1$
        } else {
            m_tooltip.setTooltip(StringUtils.EMPTY);
        }
    }

    private IKalypsoTheme findTheme(final Object object) {
        if (object instanceof IKalypsoTheme)
            return (IKalypsoTheme) object;

        if (object instanceof IAdaptable) {
            final IAdaptable adapable = (IAdaptable) object;
            final IKalypsoTheme theme = (IKalypsoTheme) adapable.getAdapter(IKalypsoTheme.class);
            if (theme != null)
                return theme;
        }

        return null;
    }

    @Override
    public void mouseMoved(final MouseEvent e) {
        final IMapPanel mapPanel = getMapPanel();
        if (mapPanel == null)
            return;

        final Point p = e.getPoint();

        final GM_Point currentPoint = MapUtilities.transform(mapPanel, p);
        updateTooltip(currentPoint);

        repaintMap();
    }

    private void updateTooltip(final GM_Point currentPoint) {
        final String tooltip = getTooltip(currentPoint);
        m_tooltip.setTooltip(tooltip);
    }

    private String getTooltip(final GM_Point currentPoint) {
        final Set<Feature> featureList = m_widgetFace.getFeatures();

        if (featureList == null || featureList.isEmpty())
            return StringUtils.EMPTY;

        for (final Object element : featureList) {
            final Feature lActFeature = (Feature) element;
            if (lActFeature != null) {
                // FIXME: bad and ugly: 0.9 constant: use converted pixel distance instead!
                final GM_Object geometry = lActFeature.getDefaultGeometryPropertyValue();
                final boolean isPointNear = currentPoint.isWithinDistance(geometry, 0.9);

                // FIXME: snd check should not be necessary -> probably first check is bad
                if (isPointNear || geometry.contains(currentPoint.getPosition())) {
                    return lActFeature.getId() + "\n" //$NON-NLS-1$
                            + getSimpleFeatureInfo(lActFeature, lActFeature.getFeatureType());
                }
            }
        }

        return StringUtils.EMPTY;
    }

    // FIXME: ugly! use already existing theme info or similar mechanism
    private String getSimpleFeatureInfo(final Object featureObj, final Object featureType) {
        String lStrInfo = ""; //$NON-NLS-1$
        if (featureObj instanceof Feature) {
            final Feature feature = (Feature) featureObj;
            final IFeatureType lPropType = (IFeatureType) featureType;

            for (int i = 0; i < feature.getProperties().length; i++) {
                final Object prop = feature.getProperties()[i];
                if (!(prop instanceof String) && prop instanceof List) {
                    lStrInfo += getSimpleFeatureInfo(prop,
                            featureType == null ? null : lPropType.getProperties()[i]); //$NON-NLS-1$
                } else if (prop != null) {
                    String lStrPrefix = ""; //$NON-NLS-1$
                    if (featureType != null) {
                        lStrPrefix = lPropType.getProperties()[i].getQName().getLocalPart() + ": "; //$NON-NLS-1$
                    }
                    final String lPropTrim = ("" + prop).trim(); //$NON-NLS-1$
                    if (!"".equals(lPropTrim)) { //$NON-NLS-1$ //$NON-NLS-2$
                        if (lPropTrim.length() > m_maxStrLen) {
                            lStrInfo += lStrPrefix + lPropTrim.substring(0, m_maxStrLen) + " ...\n"; //$NON-NLS-1$
                        } else {
                            lStrInfo += lStrPrefix + lPropTrim + "\n"; //$NON-NLS-1$
                        }
                    }

                }
            }
        } else if (featureObj instanceof List) {
            final List<?> featureList = (List<?>) featureObj;
            String lStrSuffix = ""; //$NON-NLS-1$
            String lStrPrefix = ""; //$NON-NLS-1$
            if (featureType != null) {
                final IPropertyType propertyType = (IPropertyType) featureType;
                lStrPrefix = propertyType.getQName().getLocalPart() + ": "; //$NON-NLS-1$
            }
            for (int i = 0; i < featureList.size(); i++) {
                final Object prop = featureList.get(i);
                if (!"".equals(("" + prop).trim())) //$NON-NLS-1$ //$NON-NLS-2$
                    if (("" + prop).trim().length() > m_maxStrLen) //$NON-NLS-1$
                    {
                        lStrSuffix += ("" + prop).trim().substring(0, m_maxStrLen) + " ... , "; //$NON-NLS-1$ //$NON-NLS-2$
                    } else {
                        lStrSuffix += prop + ", "; //$NON-NLS-1$
                    }
            }
            if (!"".equals(lStrSuffix.trim())) { //$NON-NLS-1$
                lStrInfo += lStrPrefix + lStrSuffix + "\n"; //$NON-NLS-1$
            }
        } else if (featureObj != null) {
            lStrInfo += featureObj + "\n"; //$NON-NLS-1$
        }
        return lStrInfo;
    }

    void reset() {
        m_widgetFace.clear();

        m_tooltip.setTooltip(Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.11")); //$NON-NLS-1$

        repaintMap();
    }

    @Override
    public void paint(final Graphics g) {
        final Feature feature = m_widgetFace.getFeature();
        if (feature == null)
            return;

        final Set<Feature> featureList = m_widgetFace.getFeatures();

        for (final Feature element : featureList) {
            try {
                final GM_Object geometryObjectValue = element.getDefaultGeometryPropertyValue();
                final GM_Envelope envelope = geometryObjectValue.getEnvelope();
                GM_Object geometryObjectToShow = geometryObjectValue;

                double scaledFactor = getMapPanel().getCurrentScale();

                // FIXME: mega ugly!
                if (envelope.getMaxX() == envelope.getMinX() && envelope.getMaxY() == envelope.getMinY()) {
                    scaledFactor *= 0.00093;
                } else {
                    scaledFactor *= 0.0000093;
                }

                geometryObjectToShow = geometryObjectValue.getBuffer(scaledFactor);
                final PolygonSymbolizer symb = new PolygonSymbolizer_Impl();

                final Stroke stroke = new Stroke_Impl(new HashMap<String, CssParameter>(), null, null);
                stroke.setWidth(5);
                stroke.setStroke(new Color(255, 0, 0));
                symb.setStroke(stroke);

                // FIXME:; why m_feature and not element?!
                final DisplayElement de = DisplayElementFactory.buildPolygonDisplayElement(feature,
                        geometryObjectToShow, symb);
                de.paint(g, getMapPanel().getProjection(), new NullProgressMonitor());
            } catch (final Exception e) {
            }
        }

        // FIXME: only painted, if m_feature != null
        m_tooltip.paintToolTip(getMapPanel().getScreenBounds().getLocation(), g, getMapPanel().getScreenBounds());
    }

    @Override
    public String getPartName() {
        return Messages.getString("org.kalypso.ogc.gml.map.widgets.FindElementMapWidget.1"); //$NON-NLS-1$
    }

    @Override
    public synchronized boolean canBeActivated(final ISelection selection, final IMapPanel mapPanel) {
        try {
            final IWorkbenchPage activePage = findActivePage();
            final MapWidgetView widgetView = (MapWidgetView) activePage.findView(MapWidgetView.ID);

            if (widgetView != null)
                return false;

            return super.canBeActivated(selection, mapPanel);
        } catch (final Exception e) {
            return false;
        }
    }

    IKalypsoTheme[] getCurrentThemes() {
        return m_themesAct;
    }

    IMapPanel getPanel() {
        return m_mapPanel;
    }
}