//$HeadURL$ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2008 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.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: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.igeo.modules.analysis; import static javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT; import static javax.swing.SwingConstants.TOP; import static org.deegree.datatypes.Types.VARCHAR; import static org.deegree.framework.log.LoggerFactory.getLogger; import static org.deegree.igeo.i18n.Messages.get; import static org.deegree.igeo.views.swing.GeometryStatisticsPanel.resetGlobals; import java.awt.Component; import java.net.URI; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.UUID; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import org.deegree.datatypes.QualifiedName; import org.deegree.framework.log.ILogger; import org.deegree.igeo.commands.RefreshFeatureInfoCommand; import org.deegree.igeo.config.MemoryDatasourceType; import org.deegree.igeo.dataadapter.DataAccessAdapter; import org.deegree.igeo.dataadapter.DataAccessFactory; import org.deegree.igeo.dataadapter.FeatureAdapter; import org.deegree.igeo.desktop.IGeoDesktop; import org.deegree.igeo.mapmodel.Datasource; import org.deegree.igeo.mapmodel.Layer; import org.deegree.igeo.mapmodel.MapModel; import org.deegree.igeo.modules.ActionDescription; import org.deegree.igeo.modules.DefaultModule; import org.deegree.igeo.modules.ModuleCapabilities; import org.deegree.igeo.modules.ActionDescription.ACTIONTYPE; import org.deegree.igeo.modules.DefaultMapModule.SelectedFeaturesVisitor; import org.deegree.igeo.modules.analysis.AnalysisFunction.AnalysisFunctionException; import org.deegree.igeo.views.DialogFactory; import org.deegree.igeo.views.swing.GeometryStatisticsPanel; import org.deegree.igeo.views.swing.analysis.AnalysisPanel; import org.deegree.igeo.views.swing.analysis.AnalysisPanel.AnalysisPanelException; import org.deegree.igeo.views.swing.util.panels.PanelDialog; import org.deegree.model.feature.Feature; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.FeatureFactory; import org.deegree.model.feature.schema.FeatureType; import org.deegree.model.feature.schema.PropertyType; import org.deegree.model.spatialschema.Geometry; import org.deegree.model.spatialschema.Point; /** * <code>AnalysisModule</code> * * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> * @author last edited by: $Author$ * * @version $Revision$, $Date$ * @param <T> */ public class AnalysisModule<T> extends DefaultModule<T> { private static final ILogger LOG = getLogger( AnalysisModule.class ); static { ActionDescription ad1 = new ActionDescription( "addOrUpdateAreaAndLength", "opens a dialog that enables adding geometry length/area as properties to a feature", null, "open dialog for adding geometry length/area", ACTIONTYPE.PushButton, null, null ); ActionDescription ad2 = new ActionDescription( "geometryStatistics", "calculates statistics for each selected geometry", null, "calculates statistics for each selected geometry", ACTIONTYPE.PushButton, null, null ); moduleCapabilities = new ModuleCapabilities( ad1, ad2 ); } /** * */ public void geometryStatistics() { if ( "application".equalsIgnoreCase( appContainer.getViewPlatform() ) ) { MapModel mm = appContainer.getMapModel( null ); SelectedFeaturesVisitor visitor = new SelectedFeaturesVisitor( -1 ); try { mm.walkLayerTree( visitor ); int size = visitor.col.size(); if ( size > 0 ) { int count = 0; // preprocess to acquire accurate information on number of tabs for ( int i = 0; i < size; ++i ) { Feature feature = visitor.col.getFeature( i ); if ( feature.getDefaultGeometryPropertyValue() instanceof Point ) { continue; } ++count; } if ( count > 10 ) { int res = JOptionPane.showConfirmDialog( (Component) getViewForm(), get( "$MD10533", count ), get( "$DI10019" ), JOptionPane.YES_NO_OPTION ); if ( res == JOptionPane.NO_OPTION ) { return; } } if ( count == 0 ) { DialogFactory.openInformationDialog( "application", getViewForm(), get( "$MD10585" ), get( "$DI10018" ) ); return; } JTabbedPane tabs = new JTabbedPane( TOP, SCROLL_TAB_LAYOUT ) { private static final long serialVersionUID = -1328589403039193378L; @Override public String toString() { return get( "$MD10534" ); } }; synchronized ( GeometryStatisticsPanel.class ) { resetGlobals(); for ( int i = 0; i < size; ++i ) { Feature feature = visitor.col.getFeature( i ); Geometry geometry = feature.getDefaultGeometryPropertyValue(); if ( geometry instanceof Point ) { continue; } tabs.addTab( feature.getId(), new GeometryStatisticsPanel( geometry ) ); } tabs.addTab( get( "$MD11058" ), new GeometryStatisticsPanel( null ) ); } PanelDialog dlg = new PanelDialog( tabs, false ); dlg.setModal( false ); dlg.setVisible( true ); } else { DialogFactory.openInformationDialog( "application", getViewForm(), get( "$MD10584" ), get( "$DI10018" ) ); } } catch ( Exception e ) { LOG.logError( "Unknown error", e ); } } } /** * */ public void addOrUpdateAreaAndLength() { if ( appContainer instanceof IGeoDesktop || getViewForm() instanceof Component ) { MapModel mm = appContainer.getMapModel( null ); try { List<Layer> layers = mm.getLayersSelectedForAction( MapModel.SELECTION_ACTION ); List<AnalysisFunction> funs = new LinkedList<AnalysisFunction>(); funs.add( new LengthFunction( appContainer.getCommandProcessor() ) ); funs.add( new AreaFunction( appContainer.getCommandProcessor() ) ); AnalysisPanel panel = new AnalysisPanel( layers, funs ); PanelDialog dlg = PanelDialog.create( appContainer.getMainWndow(), panel, true ); dlg.setTitle( getName() ); dlg.setVisible( true ); if ( dlg.clickedOk ) { AnalysisFunction fun = (AnalysisFunction) panel.functionToCalculate.getSelectedItem(); if ( panel.existingProperty.isSelected() ) { fun.apply( panel.propertyMap.get( panel.propertyBox.getSelectedItem() ), layers ); } else { LinkedList<PropertyType> list = copyLayersAndAddAttribute( layers, panel.newPropName.getText() ); fun.apply( list, layers ); } } } catch ( AnalysisPanelException e ) { DialogFactory.openErrorDialog( appContainer.getViewPlatform(), (Component) getViewForm(), e.getLocalizedMessage(), get( "$DI10017" ), e ); } catch ( AnalysisFunctionException e ) { DialogFactory.openErrorDialog( appContainer.getViewPlatform(), (Component) getViewForm(), e.getLocalizedMessage(), get( "$DI10017" ), e ); } } } private LinkedList<PropertyType> copyLayersAndAddAttribute( List<Layer> layers, String name ) { LinkedList<PropertyType> pts = new LinkedList<PropertyType>(); for ( Layer l : layers ) { FeatureAdapter adapter = null; inner: for ( DataAccessAdapter a : l.getDataAccess() ) { if ( a instanceof FeatureAdapter ) { adapter = (FeatureAdapter) a; break inner; } } if ( adapter == null ) { continue; } FeatureType fs = adapter.getSchema(); URI ns = fs.getNameSpace(); QualifiedName qn = new QualifiedName( fs.getName().getPrefix(), name, ns ); if ( fs.getProperty( qn ) != null ) { LOG.logDebug( "Schema for layer " + l.getTitle() + " already contains an attribute named " + name ); } else { List<PropertyType> props = new LinkedList<PropertyType>( Arrays.asList( fs.getProperties() ) ); pts.add( FeatureFactory.createSimplePropertyType( qn, VARCHAR, true ) ); props.add( pts.getLast() ); // TODO create as varchar always? double? fs = FeatureFactory.createFeatureType( fs.getName(), false, props.toArray( new PropertyType[props.size()] ) ); } FeatureCollection fc = adapter.getFeatureCollection(); for ( int i = 0; i < fc.size(); ++i ) { fc.getFeature( i ).setFeatureType( fs ); } Datasource oldDatasource = adapter.getDatasource(); MemoryDatasourceType dsType = new MemoryDatasourceType(); dsType.setName( UUID.randomUUID().toString() ); Datasource newDatasource = DataAccessFactory.createDatasource( oldDatasource.getName(), fc ); newDatasource.setCache( oldDatasource.getCache() ); newDatasource.setAuthenticationInformation( oldDatasource.getAuthenticationInformation() ); l.removeDatasource( oldDatasource ); l.addDatasource( newDatasource ); try { appContainer.getCommandProcessor().executeSychronously( new RefreshFeatureInfoCommand(), true ); } catch ( Exception e ) { LOG.logError( "Unknown error", e ); } } return pts; } }