/*---------------- 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
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.tools.wms;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.ColorUtils;
import org.deegree.framework.xml.NamespaceContext;
import org.deegree.framework.xml.XMLFragment;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.XMLTools;
import org.deegree.framework.xml.XSLTDocument;
import org.deegree.graphics.sld.AbstractLayer;
import org.deegree.graphics.sld.NamedLayer;
import org.deegree.graphics.sld.StyleFactory;
import org.deegree.graphics.sld.StyledLayerDescriptor;
import org.deegree.graphics.sld.UserStyle;
import org.deegree.ogcbase.CommonNamespaces;
import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
import org.w3c.dom.Node;
/**
* creates a deegree WMS configuration document or a Layer section from
* a WFS capabilities document. The datasource type for each layer will
* be LOCALWFS. Also a style with random color(s) will be created, assigned
* to the layers and stored in a xml document named $OUTFILE_BASE$_styles.xml.
* TODO
* support for usage of an already existing WMS configuration document
* TODO
* determine geometry types of the feature types registered within the
* wfs capabilities document
*
*
* @version $Revision: 1.4 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author last edited by: $Author: poth $
*
* @version 1.0. $Revision: 1.4 $, $Date: 2006/10/17 20:31:18 $
*
* @since 2.0
*/
public class WFS2WMS {
private static NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
private ILogger LOG = LoggerFactory.getLogger( WFS2WMS.class );
private URL xsl = WFS2WMS.class.getResource( "wfs2wms.xsl" );
private Properties prop = null;
public WFS2WMS( Properties prop ) {
this.prop = prop;
}
public static double getMinX( Node node ) {
double v = -180;
try {
String s = XMLTools.getNodeAsString( node, ".", nsc, "-180 -90" );
String[] t = s.split( " " );
v = Double.parseDouble( t[0] );
} catch ( XMLParsingException e ) {
e.printStackTrace();
}
return v;
}
public static double getMinY( Node node ) {
double v = -90;
try {
String s = XMLTools.getNodeAsString( node, ".", nsc, "-180 -90" );
String[] t = s.split( " " );
v = Double.parseDouble( t[1] );
} catch ( XMLParsingException e ) {
e.printStackTrace();
}
return v;
}
public static double getMaxX( Node node ) {
double v = 180;
try {
String s = XMLTools.getNodeAsString( node, ".", nsc, "180 90" );
String[] t = s.split( " " );
v = Double.parseDouble( t[0] );
} catch ( XMLParsingException e ) {
e.printStackTrace();
}
return v;
}
public static double getMaxY( Node node ) {
double v = 90;
try {
String s = XMLTools.getNodeAsString( node, ".", nsc, "180 90" );
String[] t = s.split( " " );
v = Double.parseDouble( t[1] );
} catch ( XMLParsingException e ) {
e.printStackTrace();
}
return v;
}
/**
* append all required namespace definition to the root element
* @param xml
* @return
* @throws InvalidCapabilitiesException
*/
private XMLFragment addNamespaces( XMLFragment wms, WFSCapabilities capa ) {
WFSFeatureType[] fts = capa.getFeatureTypeList().getFeatureTypes();
for ( int i = 0; i < fts.length; i++ ) {
QualifiedName qn = fts[i].getName();
XMLTools.appendNSBinding( wms.getRootElement(), qn.getPrefix(), qn.getNamespace() );
}
return wms;
}
/**
* creates a style for each feature type registered in a WFS capabilities
* document
*
* @param wfs
* @return
*/
private List<UserStyle> createStyles( WFSCapabilities capa ) {
List<UserStyle> styles = new ArrayList<UserStyle>();
Map<QualifiedName, Integer> types = determineGeometryType( capa );
WFSFeatureType[] fts = capa.getFeatureTypeList().getFeatureTypes();
UserStyle st = null;
for ( int i = 0; i < fts.length; i++ ) {
QualifiedName qn = fts[i].getName();
int type = types.get( qn );
switch ( type ) {
case 1: {
st = (UserStyle) StyleFactory.createPointStyle( "square", ColorUtils.getRandomColor( false ),
ColorUtils.getRandomColor( false ), 1,
1, 10, 10, 0, Double.MAX_VALUE );
break;
}
case 2: {
st = (UserStyle) StyleFactory.createLineStyle( ColorUtils.getRandomColor( false ),
4, 1, 0, Double.MAX_VALUE );
break;
}
case 3: {
st = (UserStyle) StyleFactory.createPolygonStyle( ColorUtils.getRandomColor( false ),
1,
ColorUtils.getRandomColor( false ),
1, 1, 0, Double.MAX_VALUE );
break;
}
}
st.setName( "default:" + qn.getAsString() );
styles.add( st );
}
return styles;
}
/**
*
* @param styles
* @return
*/
private StyledLayerDescriptor createSLD( List<UserStyle> styles ) {
UserStyle[] us = styles.toArray( new UserStyle[styles.size()] );
NamedLayer nl = new NamedLayer( "defaultstyle", null, us );
return new StyledLayerDescriptor( new AbstractLayer[] { nl }, "1.0.0" );
}
/**
* returns the geometrytype of each feature type registered within the
* passed WFS capabilities document<br>
* <ul>
* <li>1 = point or multi point
* <li>2 = curve or multi curve
* <li>3 = surface or multi surface
* </ul>
* @param capa
* @return
*/
private Map<QualifiedName, Integer> determineGeometryType( WFSCapabilities capa ) {
Map<QualifiedName, Integer> types = new HashMap<QualifiedName, Integer>();
WFSFeatureType[] fts = capa.getFeatureTypeList().getFeatureTypes();
for ( int i = 0; i < fts.length; i++ ) {
QualifiedName qn = fts[i].getName();
// TODO
// get real geometry type
types.put( qn, 3 );
}
return types;
}
/**
* method the starts running the conversation
*
* @throws Exception
*/
public void run() throws Exception {
String out = prop.getProperty( "-outFile" );
File file = new File( out );
int pos = file.getName().lastIndexOf('.');
String styleDoc = file.getName().substring( 0, pos ) + "_styles.xml";
HashMap param = new HashMap();
param.put( "PARENTLAYER", prop.getProperty( "-parentLayer" ) );
param.put( "MINX", prop.getProperty( "-minx" ) );
param.put( "MINY", prop.getProperty( "-miny" ) );
param.put( "MAXX", prop.getProperty( "-maxx" ) );
param.put( "MAXY", prop.getProperty( "-maxy" ) );
param.put( "SRS", prop.getProperty( "-srs" ) );
if ( "true".equals( prop.getProperty( "-full" ) ) ) {
param.put( "WMSCAPS", "1" );
}
param.put( "STYLEDOC", styleDoc );
LOG.logInfo( "XSLT-parameter: ", param );
XSLTDocument outXSLSheet = new XSLTDocument();
outXSLSheet.load( xsl );
file = new File( prop.getProperty( "-wfsCaps" ) );
param.put( "WFSCAPS", file.toURL().toExternalForm() );
XMLFragment doc = new XMLFragment();
doc.load( file.toURL() );
XMLFragment resultDocument = outXSLSheet.transform( doc, null, null, param );
WFSCapabilitiesDocument wfsdoc = new WFSCapabilitiesDocument();
wfsdoc.setRootElement( doc.getRootElement() );
WFSCapabilities capa = (WFSCapabilities) wfsdoc.parseCapabilities();
resultDocument = addNamespaces( resultDocument, capa );
List styles = createStyles( capa );
StyledLayerDescriptor sld = createSLD( styles );
String s = prop.getProperty( "-outFile" ).replace( ".xml", "_styles.xml" );
file = new File( s );
FileOutputStream fos = new FileOutputStream( file );
fos.write( sld.exportAsXML().getBytes() );
fos.close();
file = new File( prop.getProperty( "-outFile" ) );
fos = new FileOutputStream( file );
resultDocument.write( fos );
fos.close();
}
private static void validate( Properties map )
throws Exception {
if ( map.get( "-parentLayer" ) == null ) {
throw new Exception( Messages.getString( "WFS2WMS.validate_2" ) );
}
if ( map.get( "-minx" ) != null ) {
Double.parseDouble( map.getProperty( "-minx" ) );
} else {
map.put( "-minx", "-180" );
}
if ( map.get( "-miny" ) != null ) {
Double.parseDouble( map.getProperty( "-miny" ) );
} else {
map.put( "-miny", "-90" );
}
if ( map.get( "-maxx" ) != null ) {
Double.parseDouble( map.getProperty( "-maxx" ) );
} else {
map.put( "-maxx", "180" );
}
if ( map.get( "-maxy" ) != null ) {
Double.parseDouble( map.getProperty( "-maxy" ) );
} else {
map.put( "-maxy", "90" );
}
if ( map.get( "-srs" ) == null ) {
map.put( "-srs", "EPSG:4326" );
}
if ( map.get( "-wfsCaps" ) == null ) {
throw new Exception( Messages.getString( "WFS2WMS.validate_0" ) );
}
if ( map.get( "-outFile" ) == null ) {
throw new Exception( Messages.getString( "WFS2WMS.validate_1" ) );
}
}
/**
* @param args
*/
public static void main( String[] args )
throws Exception {
Properties map = new Properties();
for ( int i = 0; i < args.length; i += 2 ) {
System.out.println( args[i + 1] );
map.put( args[i], args[i + 1] );
}
try {
validate( map );
} catch ( Exception e ) {
System.out.println( "!!! E R R O R !!!" );
System.out.println( e.getMessage() );
System.out.println( "----------------------------------------------------" );
System.out.println( Messages.getString( "WFS2WMS.parentLayer" ) );
System.out.println( Messages.getString( "WFS2WMS.wfsCaps" ) );
System.out.println( Messages.getString( "WFS2WMS.outFile" ) );
return;
}
WFS2WMS wfs2wms = new WFS2WMS( map );
wfs2wms.run();
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: WFS2WMS.java,v $
Revision 1.4 2006/10/17 20:31:18 poth
*** empty log message ***
Revision 1.3 2006/06/05 19:27:36 poth
support for automatic style creation (just polygons) and explict defintion of wfs capabilities source in result Layer/datasource elements added
Revision 1.2 2006/06/05 15:22:52 poth
*** empty log message ***
Revision 1.1 2006/06/04 19:16:33 poth
initial load up (not tested)
********************************************************************** */