//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wpvs/WFSInvoker.java,v 1.35 2006/11/27 15:43:34 bezema Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, 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
Aennchenstraße 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.ogcwebservices.wpvs;
import java.io.StringReader;
import java.util.ArrayList;
import org.deegree.datatypes.QualifiedName;
import org.deegree.datatypes.Types;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.CharsetUtils;
import org.deegree.framework.util.IDGenerator;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.XMLTools;
import org.deegree.model.feature.Feature;
import org.deegree.model.feature.FeatureCollection;
import org.deegree.model.feature.FeatureProperty;
import org.deegree.model.feature.schema.FeatureType;
import org.deegree.model.feature.schema.PropertyType;
import org.deegree.model.filterencoding.ComplexFilter;
import org.deegree.model.filterencoding.FeatureFilter;
import org.deegree.model.filterencoding.FeatureId;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.spatialschema.GMLGeometryAdapter;
import org.deegree.model.spatialschema.GeometryException;
import org.deegree.ogcbase.PropertyPath;
import org.deegree.ogcwebservices.OGCWebService;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
import org.deegree.ogcwebservices.wfs.operation.GetFeature;
import org.deegree.ogcwebservices.wpvs.configuration.AbstractDataSource;
import org.deegree.ogcwebservices.wpvs.configuration.LocalWFSDataSource;
import org.deegree.ogcwebservices.wpvs.j3d.DefaultSurface;
import org.deegree.ogcwebservices.wpvs.j3d.Object3DFactory;
import org.deegree.ogcwebservices.wpvs.j3d.PointsToPointListFactory;
import org.deegree.ogcwebservices.wpvs.util.ResolutionStripe;
import org.w3c.dom.Document;
/**
* Invoker for a Web Feature Service.
*
* @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
* @author last edited by: $Author: bezema $
*
* @version 2.0, $Revision: 1.35 $, $Date: 2006/11/27 15:43:34 $
*
* @since 2.0
*/
public class WFSInvoker extends GetViewServiceInvoker {
private static final ILogger LOG = LoggerFactory.getLogger( WFSInvoker.class );
/* whether the returned data is a 3D object or data for the elevation model */
private final boolean isElevationModelRequest;
private int id;
/**
* Creates a new instance of this class.
*
* @param owner
* the ResolutionStripe that calls this invoker
* @param id
* @param isElevationModelRequest
*/
public WFSInvoker( ResolutionStripe owner, int id, boolean isElevationModelRequest ) {
super( owner );
this.id = id;
this.isElevationModelRequest = isElevationModelRequest;
}
@Override
public void invokeService( AbstractDataSource dataSource ) {
LOG.entering();
if ( !( dataSource instanceof LocalWFSDataSource ) ) {
LOG.logError( "The given AbstractDataSource is no WFSDataSource instance. It is needed for a WFSInvoker" );
throw new RuntimeException( "DataSource should be a WFS-instance for a WFCSInvoker" );
}
OGCWebService service = dataSource.getOGCWebService();
if ( service == null ) {
LOG.logError( "The given AbstractDataSource is no WFSDataSource instance. It is needed for a WFSInvoker" );
throw new RuntimeException( "DataSource should be a WFS-instance for a WFCSInvoker" );
}
Object response = null;
try {
GetFeature getFeature = createGetFeatureRequest( (LocalWFSDataSource) dataSource );
response = service.doService( getFeature );
} catch ( OGCWebServiceException ogcwe ) {
LOG.logError( "Exception when performing GetFeature: ", ogcwe );
ogcwe.printStackTrace();
} catch ( GeometryException ge ) {
LOG.logError( "Exception when creating GetFeature request: ", ge );
ge.printStackTrace();
}
if ( response != null && response instanceof FeatureResult ) {
FeatureCollection result = (FeatureCollection) ( (FeatureResult) response ).getResponse();
if ( result != null ) {
LOG.logDebug( "RESULT: " + result.size() );
if ( isElevationModelRequest ) {
// PointListFactory adapter = (PointListFactory) ( (LocalWFSDataSource) dataSource ).getFeatureCollectionAdapter();
PointsToPointListFactory ptpFac = new PointsToPointListFactory();
resolutionStripe.setElevationModelFromMeassurePoints( ptpFac.createFromFeatureCollection( result ) );
} else {
Object3DFactory o3DFactory = new Object3DFactory();
for ( int i = 0; i < result.size(); ++i ) {
Feature feature = result.getFeature( i );
createSurfaces( o3DFactory, feature );
}
}
}
}
LOG.exiting();
}
/**
* This method recursively constructs all the surfaces contained in the given feature. If the
* Feature contains a PropertyType of {@link Types#FEATURE} this Feature will also be traversed, if it
* contains a {@link Types#GEOMETRY} a {@link DefaultSurface} will be created.
*
* @param o3DFactory the Factory to create the defaultservice
* @param feature the feature to traverse.
*/
private void createSurfaces( Object3DFactory o3DFactory, Feature feature ) {
FeatureType ft = feature.getFeatureType();
PropertyType[] propertyTypes = ft.getProperties();
for ( PropertyType pt : propertyTypes ) {
if ( pt.getType() == Types.FEATURE ) {
FeatureProperty[] fp = feature.getProperties( pt.getName() );
if ( fp != null ) {
for ( int i = 0; i < fp.length; i++ ) {
createSurfaces( o3DFactory, (Feature) fp[i].getValue() );
}
}
} else if ( pt.getType() == Types.GEOMETRY ) {
DefaultSurface ds = o3DFactory.createSurface( feature );
if ( ds != null ) {
resolutionStripe.addFeature( id + "_" + ds.getDefaultSurfaceID(), ds );
}
}
}
}
/**
* Creates a new <code>GetFeature</code> object from an "XML-String" not nice.
*
* @param ds
* the datasource containig service data
* @param id
* the request id
* @return a new GetFeature request
* @throws GeometryException
* @throws OGCWebServiceException
* @throws Exception
*/
private GetFeature createGetFeatureRequest( LocalWFSDataSource dataSource /*
* String id,
* Surface[] boxes
*/)
throws GeometryException, OGCWebServiceException {
QualifiedName qn = dataSource.getName();
StringBuffer sb = new StringBuffer( 5000 );
sb.append( "<?xml version='1.0' encoding='" + CharsetUtils.getSystemCharset() + "'?>" );
sb.append( "<wfs:GetFeature xmlns:wfs='http://www.opengis.net/wfs' " );
sb.append( "xmlns:ogc='http://www.opengis.net/ogc' " );
sb.append( "xmlns:gml='http://www.opengis.net/gml' " );
sb.append( "xmlns:" ).append( qn.getPrefix() ).append( '=' );
sb.append( "'" ).append( qn.getNamespace() ).append( "' " );
if ( dataSource.getServiceType() == AbstractDataSource.LOCAL_WFS ) {
sb.append( "outputFormat='FEATURECOLLECTION'>" );
} else {
sb.append( "outputFormat='text/xml; subtype=gml/3.1.1'>" );
}
/**
* To make things a little clearer compare with this SQL-Statement: SELECT ( !texture )?
* geoProperty : * FROM qn.getLocalName() WHERE geoPoperty intersects with
* resolutionStripe.getSurface() AND FilterConditions.
*/
PropertyPath geoProperty = dataSource.getGeometryProperty();
// FROM
sb.append( "<wfs:Query typeName='" ).append( qn.getPrefix() ).append( ":" );
sb.append( qn.getLocalName() ).append( "'>" );
// SELECT
if ( !isElevationModelRequest ) {
sb.append( "<wfs:PropertyName>" );
sb.append( geoProperty.getAsString() );
sb.append( "</wfs:PropertyName>" );
}
StringBuffer sbArea = GMLGeometryAdapter.export( resolutionStripe.getSurface() );
// WHERE
sb.append( "<ogc:Filter><ogc:Intersects> " );
sb.append( "<wfs:PropertyName>" );
sb.append( geoProperty.getAsString() );
sb.append( "</wfs:PropertyName>" );
sb.append( sbArea );
sb.append( "</ogc:Intersects>" );
// AND
Filter filter = dataSource.getFilter();
if ( filter != null ) {
if ( filter instanceof ComplexFilter ) {
sb.append( "<ogc:And>" );
sb.append( "<ogc:BBOX>" );
sb.append( "<wfs:PropertyName>" );
sb.append( dataSource.getGeometryProperty().getAsString() );
sb.append( "</wfs:PropertyName>" );
sb.append( GMLGeometryAdapter.exportAsBox( resolutionStripe.getSurface().getEnvelope() ) );
sb.append( "</ogc:BBOX>" );
// add filter as defined in the layers datasource description
// to the filter expression
org.deegree.model.filterencoding.Operation op = ( (ComplexFilter) filter ).getOperation();
sb.append( op.toXML() ).append( "</ogc:And>" );
} else {
if ( filter instanceof FeatureFilter ) {
ArrayList<FeatureId> featureIds = ( (FeatureFilter) filter ).getFeatureIds();
if ( featureIds.size() != 0 )
sb.append( "<ogc:And>" );
for ( FeatureId fid : featureIds ) {
sb.append( fid.toXML() );
}
if ( featureIds.size() != 0 )
sb.append( "</ogc:And>" );
}
}
}
sb.append( "</ogc:Filter></wfs:Query></wfs:GetFeature>" );
String s = sb.toString();
Document doc;
try {
doc = XMLTools.parse( new StringReader( s ) );
} catch ( Exception e ) {
e.printStackTrace();
String mesg = "Could not parse GetFeature request ";
LOG.logError( StringTools.concat( s.length() + 100, mesg, sb.toString() ) );
throw new OGCWebServiceException( mesg );
}
LOG.logDebug( "WFS GetFeature: " + s );
IDGenerator idg = IDGenerator.getInstance();
return GetFeature.create( String.valueOf( idg.generateUniqueID() ),
doc.getDocumentElement() );
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to: $Log: WFSInvoker.java,v $
* Changes to this class. What the people have been up to: Revision 1.35 2006/11/27 15:43:34 bezema
* Changes to this class. What the people have been up to: Updated the coordinatesystem handling
* Changes to this class. What the people have been up to:
* Changes to this class. What the people have been up to: Revision 1.34 2006/11/23 11:46:14 bezema
* Changes to this class. What the people have been up to: The initial version of the new wpvs
* Changes to this class. What the people have been up to: Changes to this
* class. What the people have been up to: Revision 1.32 2006/07/20 08:12:21 taddei Changes to this
* class. What the people have been up to: use of QualiName for geometry property Changes to this
* class. What the people have been up to: Changes to this class. What the people have been up to:
* Revision 1.31 2006/07/05 15:57:47 poth Changes to this class. What the people have been up to:
* useless parameter removed from method signature Changes to this class. What the people have been
* up to: Changes to this class. What the people have been up to: Revision 1.30 2006/07/05 11:22:10
* taddei Changes to this class. What the people have been up to: include par to set buildings elev
* to 0 Changes to this class. What the people have been up to: Changes to this class. What the
* people have been up to: Revision 1.29 2006/07/04 09:06:22 taddei Changes to this class. What the
* people have been up to: todo: excp handling Changes to this class. What the people have been up
* to: Changes to this class. What the people have been up to: Revision 1.28 2006/06/29 16:50:09
* poth Changes to this class. What the people have been up to: *** empty log message *** Changes to
* this class. What the people have been up to: Changes to this class. What the people have been up
* to: Revision 1.27 2006/06/20 10:16:01 taddei Changes to this class. What the people have been up
* to: clean up and javadoc Changes to this class. What the people have been up to: Changes to this
* class. What the people have been up to: Revision 1.26 2006/06/20 07:39:59 taddei Changes to this
* class. What the people have been up to: added parent dataset and change in ft name Changes to
* this class. What the people have been up to: Changes to this class. What the people have been up
* to: Revision 1.25 2006/05/12 13:12:45 taddei Changes to this class. What the people have been up
* to: clean up Changes to this class. What the people have been up to: Changes to this class. What
* the people have been up to: Revision 1.24 2006/05/10 15:01:19 taddei Changes to this class. What
* the people have been up to: now collecting boxes into a united geom Changes to this class. What
* the people have been up to: Revision 1.23 2006/05/05 12:41:02 taddei added to to list
*
* Revision 1.22 2006/04/18 18:20:26 poth ** empty log message ***
*
* Revision 1.21 2006/04/06 20:25:30 poth ** empty log message ***
*
* Revision 1.20 2006/04/06 15:07:59 taddei added support for ValidArea
*
* Revision 1.19 2006/04/05 09:07:03 taddei added code for computing res of different surfs; and fc
* adapter
*
* Revision 1.17 2006/03/29 15:08:21 taddei with buildings
*
* Revision 1.16 2006/03/10 10:31:40 taddei changes regarding cood sys and scale calculation
*
* Revision 1.15 2006/03/09 08:57:58 taddei debug mesgs
*
* Revision 1.14 2006/03/07 08:49:20 taddei changes due to pts list factories
*
* Revision 1.13 2006/03/02 15:23:52 taddei using now StringTools and StringBuilder
*
* Revision 1.12 2006/02/22 17:12:31 taddei implemented correct drawing order
*
* Revision 1.11 2006/02/22 13:36:02 taddei refactoring: added service, createOGCWebService; also
* better except handling
*
* Revision 1.10 2006/02/17 13:38:12 taddei bug fix when counting (resol was using wrong dim) and
* fixed � (sz)
*
* Revision 1.9 2006/02/14 15:21:41 taddei now working with remote WFS
*
* Revision 1.8 2006/02/09 15:47:24 taddei bug fixes, refactoring and javadoc
*
* Revision 1.7 2006/01/30 14:58:37 taddei minor internal refactoring
*
* Revision 1.6 2006/01/27 10:39:13 taddei query optmization
*
* Revision 1.5 2006/01/26 14:42:31 taddei WMS and WFS invokers woring; minor refactoring
*
* Revision 1.4 2006/01/18 10:21:07 taddei putting wfs service to work
*
* Revision 1.3 2006/01/18 08:59:36 taddei commented out (due to wrong refactoring); fix is coming
*
* Revision 1.2 2006/01/18 08:58:00 taddei implementation (WFS)
*
* Revision 1.1 2005/12/16 15:19:11 taddei added DeafultViewHandler and the Invokers
*
*
**************************************************************************************************/